chewy 0.6.2 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -1
- data/.travis.yml +35 -29
- data/Appraisals +37 -0
- data/CHANGELOG.md +115 -4
- data/Gemfile +2 -3
- data/README.md +135 -40
- data/chewy.gemspec +4 -3
- data/gemfiles/rails.3.2.activerecord.gemfile +13 -0
- data/gemfiles/rails.3.2.activerecord.kaminari.gemfile +14 -0
- data/gemfiles/rails.3.2.activerecord.will_paginate.gemfile +14 -0
- data/gemfiles/rails.4.0.activerecord.gemfile +13 -0
- data/gemfiles/rails.4.0.activerecord.kaminari.gemfile +14 -0
- data/gemfiles/rails.4.0.activerecord.will_paginate.gemfile +14 -0
- data/gemfiles/rails.4.0.mongoid.gemfile +13 -0
- data/gemfiles/rails.4.0.mongoid.kaminari.gemfile +14 -0
- data/gemfiles/rails.4.0.mongoid.will_paginate.gemfile +14 -0
- data/gemfiles/rails.4.1.activerecord.gemfile +13 -0
- data/gemfiles/rails.4.1.activerecord.kaminari.gemfile +14 -0
- data/gemfiles/rails.4.1.activerecord.will_paginate.gemfile +14 -0
- data/gemfiles/rails.4.1.mongoid.gemfile +13 -0
- data/gemfiles/rails.4.1.mongoid.kaminari.gemfile +14 -0
- data/gemfiles/rails.4.1.mongoid.will_paginate.gemfile +14 -0
- data/gemfiles/rails.4.2.activerecord.gemfile +13 -0
- data/gemfiles/rails.4.2.activerecord.kaminari.gemfile +14 -0
- data/gemfiles/rails.4.2.activerecord.will_paginate.gemfile +14 -0
- data/gemfiles/rails.4.2.mongoid.gemfile +13 -0
- data/gemfiles/rails.4.2.mongoid.kaminari.gemfile +14 -0
- data/gemfiles/rails.4.2.mongoid.will_paginate.gemfile +14 -0
- data/lib/chewy.rb +65 -0
- data/lib/chewy/config.rb +44 -93
- data/lib/chewy/errors.rb +14 -5
- data/lib/chewy/fields/base.rb +8 -7
- data/lib/chewy/fields/root.rb +2 -2
- data/lib/chewy/index.rb +7 -9
- data/lib/chewy/log_subscriber.rb +34 -0
- data/lib/chewy/query.rb +41 -27
- data/lib/chewy/query/criteria.rb +28 -23
- data/lib/chewy/query/scoping.rb +20 -0
- data/lib/chewy/railtie.rb +51 -13
- data/lib/chewy/repository.rb +61 -0
- data/lib/chewy/rspec/update_index.rb +3 -6
- data/lib/chewy/search.rb +28 -7
- data/lib/chewy/strategy.rb +60 -0
- data/lib/chewy/strategy/atomic.rb +31 -0
- data/lib/chewy/strategy/base.rb +27 -0
- data/lib/chewy/strategy/bypass.rb +15 -0
- data/lib/chewy/strategy/urgent.rb +17 -0
- data/lib/chewy/type.rb +19 -5
- data/lib/chewy/type/adapter/active_record.rb +28 -117
- data/lib/chewy/type/adapter/base.rb +35 -0
- data/lib/chewy/type/adapter/mongoid.rb +23 -123
- data/lib/chewy/type/adapter/object.rb +41 -19
- data/lib/chewy/type/adapter/orm.rb +142 -0
- data/lib/chewy/type/import.rb +43 -16
- data/lib/chewy/type/observe.rb +8 -21
- data/lib/chewy/version.rb +1 -1
- data/lib/tasks/chewy.rake +8 -4
- data/spec/chewy/config_spec.rb +20 -97
- data/spec/chewy/fields/base_spec.rb +24 -11
- data/spec/chewy/fields/time_fields_spec.rb +27 -0
- data/spec/chewy/index/settings_spec.rb +2 -1
- data/spec/chewy/index_spec.rb +98 -79
- data/spec/chewy/query/criteria_spec.rb +14 -0
- data/spec/chewy/query_spec.rb +1 -1
- data/spec/chewy/repository_spec.rb +50 -0
- data/spec/chewy/search_spec.rb +100 -0
- data/spec/chewy/strategy_spec.rb +109 -0
- data/spec/chewy/type/adapter/active_record_spec.rb +110 -46
- data/spec/chewy/type/adapter/mongoid_spec.rb +123 -74
- data/spec/chewy/type/adapter/object_spec.rb +51 -34
- data/spec/chewy/type/import_spec.rb +21 -21
- data/spec/chewy/type/observe_spec.rb +26 -29
- data/spec/chewy/type_spec.rb +19 -0
- data/spec/chewy_spec.rb +19 -3
- data/spec/spec_helper.rb +1 -1
- data/spec/support/active_record.rb +2 -1
- data/spec/support/mongoid.rb +29 -38
- metadata +85 -55
- data/gemfiles/Gemfile.rails-3.2.active_record +0 -6
- data/gemfiles/Gemfile.rails-3.2.active_record.kaminari +0 -7
- data/gemfiles/Gemfile.rails-3.2.active_record.will_paginate +0 -7
- data/gemfiles/Gemfile.rails-4.0.active_record +0 -6
- data/gemfiles/Gemfile.rails-4.0.active_record.kaminari +0 -7
- data/gemfiles/Gemfile.rails-4.0.active_record.will_paginate +0 -7
- data/gemfiles/Gemfile.rails-4.0.mongoid +0 -6
- data/gemfiles/Gemfile.rails-4.0.mongoid.kaminari +0 -7
- data/gemfiles/Gemfile.rails-4.0.mongoid.will_paginate +0 -7
- data/gemfiles/Gemfile.rails-4.1.active_record +0 -6
- data/gemfiles/Gemfile.rails-4.1.active_record.kaminari +0 -7
- data/gemfiles/Gemfile.rails-4.1.active_record.will_paginate +0 -7
- data/gemfiles/Gemfile.rails-4.1.mongoid +0 -6
- data/gemfiles/Gemfile.rails-4.1.mongoid.kaminari +0 -7
- data/gemfiles/Gemfile.rails-4.1.mongoid.will_paginate +0 -7
- data/gemfiles/Gemfile.rails-4.2.active_record +0 -6
- data/gemfiles/Gemfile.rails-4.2.active_record.kaminari +0 -7
- data/gemfiles/Gemfile.rails-4.2.active_record.will_paginate +0 -7
- data/gemfiles/Gemfile.rails-4.2.mongoid +0 -6
- data/gemfiles/Gemfile.rails-4.2.mongoid.kaminari +0 -7
- data/gemfiles/Gemfile.rails-4.2.mongoid.will_paginate +0 -7
- data/spec/chewy/index/search_spec.rb +0 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 84273a240a5c4dac56535e864d042f647b655bef
|
4
|
+
data.tar.gz: a66632f1c947d9c8f446ef581139de5175c55763
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 08810417cade81d8cc563438139c1558dde2efc7321eeb1a988399b406c1339ca3bdacb56f083d6d4fc0ebdfbf3c8b7bf232c40ac034abe69f2e868d296821bd
|
7
|
+
data.tar.gz: 7c0cf989f04a92fea804ff67490f623037119ed58ab54ba3e4bfdce272f2d546403313e0afb11fd522794473e9b04719d0b24a9753299538c574f8d0c326efaf
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,36 +1,42 @@
|
|
1
1
|
language: ruby
|
2
|
+
services:
|
3
|
+
- mongodb
|
2
4
|
rvm:
|
3
5
|
- 2.0.0
|
4
|
-
- 2.1.
|
6
|
+
- 2.1.5
|
7
|
+
- 2.2.0
|
5
8
|
# - rbx
|
6
9
|
gemfile:
|
7
|
-
-
|
8
|
-
- gemfiles/
|
9
|
-
- gemfiles/
|
10
|
-
- gemfiles/
|
11
|
-
- gemfiles/
|
12
|
-
- gemfiles/
|
13
|
-
- gemfiles/
|
14
|
-
- gemfiles/
|
15
|
-
- gemfiles/
|
16
|
-
- gemfiles/
|
17
|
-
- gemfiles/
|
18
|
-
- gemfiles/
|
19
|
-
- gemfiles/
|
20
|
-
- gemfiles/
|
21
|
-
- gemfiles/
|
22
|
-
- gemfiles/
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
10
|
+
- gemfiles/rails.3.2.activerecord.gemfile
|
11
|
+
- gemfiles/rails.3.2.activerecord.kaminari.gemfile
|
12
|
+
- gemfiles/rails.3.2.activerecord.will_paginate.gemfile
|
13
|
+
- gemfiles/rails.4.0.activerecord.gemfile
|
14
|
+
- gemfiles/rails.4.0.activerecord.kaminari.gemfile
|
15
|
+
- gemfiles/rails.4.0.activerecord.will_paginate.gemfile
|
16
|
+
- gemfiles/rails.4.1.activerecord.gemfile
|
17
|
+
- gemfiles/rails.4.1.activerecord.kaminari.gemfile
|
18
|
+
- gemfiles/rails.4.1.activerecord.will_paginate.gemfile
|
19
|
+
- gemfiles/rails.4.2.activerecord.gemfile
|
20
|
+
- gemfiles/rails.4.2.activerecord.kaminari.gemfile
|
21
|
+
- gemfiles/rails.4.2.activerecord.will_paginate.gemfile
|
22
|
+
- gemfiles/rails.4.0.mongoid.gemfile
|
23
|
+
- gemfiles/rails.4.0.mongoid.kaminari.gemfile
|
24
|
+
- gemfiles/rails.4.0.mongoid.will_paginate.gemfile
|
25
|
+
- gemfiles/rails.4.1.mongoid.gemfile
|
26
|
+
- gemfiles/rails.4.1.mongoid.kaminari.gemfile
|
27
|
+
- gemfiles/rails.4.1.mongoid.will_paginate.gemfile
|
28
|
+
- gemfiles/rails.4.2.mongoid.gemfile
|
29
|
+
- gemfiles/rails.4.2.mongoid.kaminari.gemfile
|
30
|
+
- gemfiles/rails.4.2.mongoid.will_paginate.gemfile
|
31
|
+
matrix:
|
32
|
+
exclude:
|
33
|
+
- rvm: 2.2.0
|
34
|
+
gemfile: gemfiles/rails.3.2.activerecord.gemfile
|
35
|
+
- rvm: 2.2.0
|
36
|
+
gemfile: gemfiles/rails.3.2.activerecord.kaminari.gemfile
|
37
|
+
- rvm: 2.2.0
|
38
|
+
gemfile: gemfiles/rails.3.2.activerecord.will_paginate.gemfile
|
30
39
|
before_install:
|
31
|
-
- curl -# https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.
|
40
|
+
- curl -# https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.4.4.tar.gz | tar xz -C /tmp
|
32
41
|
before_script:
|
33
|
-
- TEST_CLUSTER_COMMAND="/tmp/elasticsearch-1.
|
34
|
-
services:
|
35
|
-
- mongodb
|
36
|
-
|
42
|
+
- TEST_CLUSTER_COMMAND="/tmp/elasticsearch-1.4.4/bin/elasticsearch" rake elasticsearch:start
|
data/Appraisals
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
%w(3.2 4.0 4.1 4.2).each do |version|
|
2
|
+
appraise "rails.#{version}.activerecord" do
|
3
|
+
gem 'activerecord', "~> #{version}.0"
|
4
|
+
gem 'activesupport', "~> #{version}.0"
|
5
|
+
end
|
6
|
+
|
7
|
+
appraise "rails.#{version}.activerecord.kaminari" do
|
8
|
+
gem 'activerecord', "~> #{version}.0"
|
9
|
+
gem 'activesupport', "~> #{version}.0"
|
10
|
+
gem 'kaminari', require: false
|
11
|
+
end
|
12
|
+
|
13
|
+
appraise "rails.#{version}.activerecord.will_paginate" do
|
14
|
+
gem 'activerecord', "~> #{version}.0"
|
15
|
+
gem 'activesupport', "~> #{version}.0"
|
16
|
+
gem 'will_paginate', require: false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
%w(4.0 4.1 4.2).each do |version|
|
21
|
+
appraise "rails.#{version}.mongoid" do
|
22
|
+
gem 'mongoid', '~> 4.0.0'
|
23
|
+
gem 'activesupport', "~> #{version}.0"
|
24
|
+
end
|
25
|
+
|
26
|
+
appraise "rails.#{version}.mongoid.kaminari" do
|
27
|
+
gem 'mongoid', '~> 4.0.0'
|
28
|
+
gem 'activesupport', "~> #{version}.0"
|
29
|
+
gem 'kaminari', require: false
|
30
|
+
end
|
31
|
+
|
32
|
+
appraise "rails.#{version}.mongoid.will_paginate" do
|
33
|
+
gem 'mongoid', '~> 4.0.0'
|
34
|
+
gem 'activesupport', "~> #{version}.0"
|
35
|
+
gem 'will_paginate', require: false
|
36
|
+
end
|
37
|
+
end
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,116 @@
|
|
1
1
|
# master
|
2
2
|
|
3
|
+
## Incompatible changes:
|
4
|
+
|
5
|
+
* `Chewy.use_after_commit_callbacks = false` returns previous RDBMS behavior
|
6
|
+
in tests.
|
7
|
+
|
8
|
+
* ActiveRecord import is now called after_commit instead of after_save and after_destroy
|
9
|
+
|
10
|
+
* Import now respects default scope and removes unmatched documents
|
11
|
+
|
12
|
+
* `delete_from_index?` method is deprecated, use
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
define_type User, delete_if: ->{ removed? } do
|
16
|
+
...
|
17
|
+
end
|
18
|
+
```
|
19
|
+
|
20
|
+
* `Chewy.request_strategy` to configure action controller's request wrapping strategy
|
21
|
+
|
22
|
+
* `Chewy.root_strategy` to configure the first strategy in stack
|
23
|
+
|
24
|
+
* Default strategy for controller actions is `:atomic`
|
25
|
+
|
26
|
+
* Default strategy for activerecord migrations is `:bypass`
|
27
|
+
|
28
|
+
* Default strategy for sandbox console is `:bypass`
|
29
|
+
|
30
|
+
* Default strategy for rails console is `:urgent`
|
31
|
+
|
32
|
+
* `Chewy.configuration` was renamed to `Chewy.settings`
|
33
|
+
|
34
|
+
* Reworked index update strategies implementation. `Chewy.atomic`
|
35
|
+
and `Chewy.urgent_update` are now deprecated in favour of the new
|
36
|
+
`Chewy.strategy` API.
|
37
|
+
|
38
|
+
* Loading objects for object-sourced types using `wrap` method is
|
39
|
+
deprecated, `load_one` method should be used instead. Or method name
|
40
|
+
might be passed to `define_type`:
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
class GeoData
|
44
|
+
def self.get_data(elasticsearch_document)
|
45
|
+
REDIS.get("geo_data_#{elasticsearch_document.id}")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
...
|
50
|
+
define_type GeoData, load_one_method: :get_data do
|
51
|
+
...
|
52
|
+
end
|
53
|
+
```
|
54
|
+
|
55
|
+
## Changes
|
56
|
+
|
57
|
+
* Multiple enhancements by @DNNX
|
58
|
+
|
59
|
+
* Added `script_fields` to search crteria (@ka8725)
|
60
|
+
|
61
|
+
* ORM adapters now completely relies on the default scope. This means every scope or objects passed to import are merged with default scope so basically there is no need to define `delete_if` block. Default scope strongly restricts objects which may land in the current index.
|
62
|
+
|
63
|
+
```ruby
|
64
|
+
define_type Country.where("rating > 30") do
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
# this code would import only countries with rating between 30 and 50
|
69
|
+
CountriesIndex::Country.import(Country.where("rating < 50"))
|
70
|
+
|
71
|
+
# the same is true for arrays of objects or ids
|
72
|
+
CountriesIndex::Country.import(Country.where("rating < 50").to_a)
|
73
|
+
CountriesIndex::Country.import(Country.where("rating < 50").pluck(:id))
|
74
|
+
```
|
75
|
+
|
76
|
+
* Object adapter supports custom initial import and load methods, so it
|
77
|
+
could be configured to be used with procs or any class responding to `call`
|
78
|
+
method.
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
class GeoData
|
82
|
+
def self.call
|
83
|
+
REDIS.get_all
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
...
|
88
|
+
define_type GeoData do
|
89
|
+
...
|
90
|
+
end
|
91
|
+
```
|
92
|
+
|
93
|
+
* Nested fields value procs additional arguments: parent objects.
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
define_type Country do
|
97
|
+
field :name
|
98
|
+
field :cities do
|
99
|
+
field :district, value: ->(city, country) { city.districts if country.main? }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
```
|
103
|
+
|
104
|
+
* Implemented basic named scopes
|
105
|
+
|
106
|
+
## Bugfixes
|
107
|
+
|
108
|
+
* `script_score` allow options (@joeljunstrom)
|
109
|
+
|
110
|
+
* Chewy indexes eaged loading fixes (@leemhenson)
|
111
|
+
|
112
|
+
* `Chewy::Index.import nil` imports nothing instead of initial data
|
113
|
+
|
3
114
|
# Version 0.6.2
|
4
115
|
|
5
116
|
## Changes
|
@@ -38,14 +149,14 @@
|
|
38
149
|
|
39
150
|
# Version 0.5.2
|
40
151
|
|
41
|
-
## Changes
|
42
|
-
|
43
|
-
* `Chewy.massacre` aliased to `Chewy.delete_all` method deletes all the indexes with current prefix
|
44
|
-
|
45
152
|
## Incompatible changes:
|
46
153
|
|
47
154
|
* `Chewy::Type::Base` removed in favour of using `Chewy::Type` as a base class for all types
|
48
155
|
|
156
|
+
## Changes
|
157
|
+
|
158
|
+
* `Chewy.massacre` aliased to `Chewy.delete_all` method deletes all the indexes with current prefix
|
159
|
+
|
49
160
|
## Bugfixes:
|
50
161
|
|
51
162
|
* Advanced type classes resolving (@inbeom)
|
data/Gemfile
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
# Specify your gem's dependencies in chewy.gemspec
|
4
3
|
gemspec
|
5
4
|
|
6
5
|
gem 'activerecord'
|
7
6
|
# gem 'mongoid'
|
8
|
-
gem 'kaminari', require: false
|
9
|
-
# gem '
|
7
|
+
# gem 'kaminari', require: false
|
8
|
+
# gem 'will_pagnate', require: false
|
10
9
|
|
11
10
|
group :test do
|
12
11
|
gem 'guard'
|
data/README.md
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
[![Code Climate](https://codeclimate.com/github/toptal/chewy.png)](https://codeclimate.com/github/toptal/chewy)
|
3
3
|
[![Inline docs](http://inch-ci.org/github/toptal/chewy.svg?branch=master)](http://inch-ci.org/github/toptal/chewy)
|
4
4
|
|
5
|
+
<p align="right">Sponsored by</p>
|
6
|
+
<p align="right"><a href="http://www.toptal.com/"><img src="http://www.toptal.com/assets/public/blocks/logo/big.png" alt="Toptal" width="105" height="34"></a></p>
|
7
|
+
|
5
8
|
# Chewy
|
6
9
|
|
7
10
|
Chewy is ODM and wrapper for official elasticsearch client (https://github.com/elasticsearch/elasticsearch-ruby)
|
@@ -18,7 +21,7 @@ Chewy is ODM and wrapper for official elasticsearch client (https://github.com/e
|
|
18
21
|
|
19
22
|
* Bulk import everywhere.
|
20
23
|
|
21
|
-
Chewy utilizes bulk ES API for full reindexing or index updates. Also it uses atomic updates concept. All the changed objects are collected inside the atomic block and index is updated once at the end of it with all the collected object. See `Chewy.atomic` for more details.
|
24
|
+
Chewy utilizes bulk ES API for full reindexing or index updates. Also it uses atomic updates concept. All the changed objects are collected inside the atomic block and index is updated once at the end of it with all the collected object. See `Chewy.strategy(:atomic)` for more details.
|
22
25
|
|
23
26
|
* Powerful querying DSL.
|
24
27
|
|
@@ -40,15 +43,15 @@ Or install it yourself as:
|
|
40
43
|
|
41
44
|
## Usage
|
42
45
|
|
43
|
-
### Client
|
46
|
+
### Client settings
|
44
47
|
|
45
|
-
There are 2 ways to configure Chewy client: `Chewy.
|
48
|
+
There are 2 ways to configure Chewy client: `Chewy.settings` hash and `chewy.yml`
|
46
49
|
|
47
50
|
You can create this file manually or run `rails g chewy:install` to do that with yaml way
|
48
51
|
|
49
52
|
```ruby
|
50
53
|
# config/initializers/chewy.rb
|
51
|
-
Chewy.
|
54
|
+
Chewy.settings = {host: 'localhost:9250'} # do not use environments
|
52
55
|
```
|
53
56
|
|
54
57
|
```yaml
|
@@ -64,7 +67,7 @@ development:
|
|
64
67
|
The result config merges both hashes. Client options are passed as is to Elasticsearch::Transport::Client except the `:prefix` - it is used internally by chewy to create prefixed index names:
|
65
68
|
|
66
69
|
```ruby
|
67
|
-
Chewy.
|
70
|
+
Chewy.settings = {prefix: 'test'}
|
68
71
|
UsersIndex.index_name # => 'test_users'
|
69
72
|
```
|
70
73
|
|
@@ -108,6 +111,8 @@ See [config.rb](lib/chewy/config.rb) for more details.
|
|
108
111
|
field :projects do # the same block syntax for multi_field, if `:type` is specified
|
109
112
|
field :title
|
110
113
|
field :description # default data type is `string`
|
114
|
+
# additional top-level objects passed to value proc:
|
115
|
+
field :categories, value: ->(project, user) { project.categories.map(&:name) if user.active? }
|
111
116
|
end
|
112
117
|
field :rating, type: 'integer' # custom data type
|
113
118
|
field :created, type: 'date', include_in_all: false,
|
@@ -196,7 +201,7 @@ You are able to access index-defined types with the following API:
|
|
196
201
|
|
197
202
|
```ruby
|
198
203
|
UsersIndex::User # => UsersIndex::User
|
199
|
-
UsersIndex.
|
204
|
+
UsersIndex.type_hash['user'] # => UsersIndex::User
|
200
205
|
UsersIndex.user # => UsersIndex::User
|
201
206
|
UsersIndex.types # => [UsersIndex::User]
|
202
207
|
UsersIndex.type_names # => ['user']
|
@@ -226,57 +231,147 @@ UsersIndex.import user: User.where('rating > 100') # import only active users to
|
|
226
231
|
UsersIndex.reset! # purges index and imports default data for all types
|
227
232
|
```
|
228
233
|
|
229
|
-
Also if passed user is `#destroyed
|
234
|
+
Also if passed user is `#destroyed?`, or satisfy `delete_if` type option, or specified id does not exists in the database, import will perform delete from index action for this object.
|
235
|
+
|
236
|
+
```ruby
|
237
|
+
define_type User, delete_if: :deleted_at
|
238
|
+
define_type User, delete_if: -> { deleted_at }
|
239
|
+
define_type User, delete_if: ->(user) { user.deleted_at }
|
240
|
+
```
|
230
241
|
|
231
242
|
See [actions.rb](lib/chewy/index/actions.rb) for more details.
|
232
243
|
|
233
|
-
###
|
244
|
+
### Index update strategies
|
245
|
+
|
246
|
+
Assume you've got the following code:
|
247
|
+
|
248
|
+
```ruby
|
249
|
+
class City < ActiveRecord::Base
|
250
|
+
update_index 'cities#city', :self
|
251
|
+
end
|
252
|
+
|
253
|
+
class CitiesIndex < Chewy::Index
|
254
|
+
define_type City do
|
255
|
+
field :name
|
256
|
+
end
|
257
|
+
end
|
258
|
+
```
|
259
|
+
|
260
|
+
If you'll perform something like `City.first.save!` you'll get
|
261
|
+
UndefinedUpdateStrategy exception instead of normal object saving
|
262
|
+
and index update. This exception forces you to choose appropriate
|
263
|
+
update strategy for current context.
|
234
264
|
|
235
|
-
|
265
|
+
If you want to return behavior was before 0.7.0 - just set
|
266
|
+
`Chewy.root_strategy = :bypass`.
|
236
267
|
|
237
|
-
|
268
|
+
#### `:atomic`
|
238
269
|
|
239
|
-
|
270
|
+
The main strategy here is `:atomic`. Assume you have to update a
|
271
|
+
lot of records in db.
|
240
272
|
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
273
|
+
```ruby
|
274
|
+
Chewy.strategy(:atomic) do
|
275
|
+
City.popular.map(&:do_some_update_action!)
|
276
|
+
end
|
277
|
+
```
|
245
278
|
|
246
|
-
|
247
|
-
|
279
|
+
Using this strategy delays index update request until the end of
|
280
|
+
block. Updated records are aggregated and index update happens with
|
281
|
+
bulk API. So this strategy is highly optimized.
|
248
282
|
|
249
|
-
####
|
283
|
+
#### `:urgent`
|
250
284
|
|
251
|
-
|
285
|
+
Next strategy is convenient if you are going to update documents in
|
286
|
+
index one-by-one.
|
252
287
|
|
253
288
|
```ruby
|
254
|
-
Chewy.
|
255
|
-
|
289
|
+
Chewy.strategy(:urgent) do
|
290
|
+
City.popular.map(&:do_some_update_action!)
|
256
291
|
end
|
257
292
|
```
|
258
293
|
|
259
|
-
|
260
|
-
|
294
|
+
This code would perform `City.popular.count` requests for ES
|
295
|
+
documents update.
|
296
|
+
|
297
|
+
Seems to be convenient for usage in e.g. rails console with
|
298
|
+
non-block notation:
|
261
299
|
|
262
300
|
```ruby
|
263
|
-
|
264
|
-
|
301
|
+
> Chewy.strategy(:urgent)
|
302
|
+
> City.popular.map(&:do_some_update_action!)
|
303
|
+
```
|
265
304
|
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
305
|
+
#### `:bypass`
|
306
|
+
|
307
|
+
Bypass strategy simply silences index updates.
|
308
|
+
|
309
|
+
#### Nesting
|
310
|
+
|
311
|
+
Strategies are designed to allow nesting, so it is possible
|
312
|
+
to redefine it for nested contexts.
|
313
|
+
|
314
|
+
```ruby
|
315
|
+
Chewy.strategy(:atomic) do
|
316
|
+
city1.do_update!
|
317
|
+
Chewy.strategy(:urgent) do
|
318
|
+
city2.do_update!
|
319
|
+
city3.do_update!
|
320
|
+
# there will be 2 update index requests for city2 and city3
|
270
321
|
end
|
322
|
+
city4..do_update!
|
323
|
+
# city1 and city4 will be grouped in one index update request
|
271
324
|
end
|
272
325
|
```
|
273
326
|
|
274
|
-
|
327
|
+
#### Non-block notation
|
328
|
+
|
329
|
+
It is possible to nest strategies without blocks:
|
330
|
+
|
331
|
+
```ruby
|
332
|
+
Chewy.strategy(:urgent)
|
333
|
+
city1.do_update! # index updated
|
334
|
+
Chewy.strategy(:bypass)
|
335
|
+
city2.do_update! # update bypassed
|
336
|
+
Chewy.strategy.pop
|
337
|
+
city3.do_update! # index updated again
|
338
|
+
```
|
339
|
+
|
340
|
+
#### Designing own strategies
|
341
|
+
|
342
|
+
Async strategy is not implemented yet, but it is planned. So
|
343
|
+
it would be a good idea to implements own async strategy for
|
344
|
+
particular delayed jobs library or simply threads.
|
345
|
+
|
346
|
+
See [strategy/base.rb](lib/chewy/strategy/base.rb) for more details.
|
347
|
+
See [strategy/atomic.rb](lib/chewy/strategy/atomic.rb) for example.
|
275
348
|
|
276
349
|
### Async reindexing
|
277
350
|
|
278
351
|
Chewy is not support async index update, but it's planned. Until you can use third-party solutions, such as [https://github.com/averell23/chewy_kiqqer](https://github.com/averell23/chewy_kiqqer)
|
279
352
|
|
353
|
+
Not sure it works currently.
|
354
|
+
|
355
|
+
### Rails application strategies integration
|
356
|
+
|
357
|
+
There is a couple of pre-defined strategies for your rails application. At first, rails console uses `:urgent` strategy by default, except the sandbox case. Whan you are running sandbox it switches to `bypass` strategy to avoid index polluting.
|
358
|
+
|
359
|
+
Also migrations are wrapped with `:bypass` strategy. Because the main behavor implies that indexes are resetted after migration, so there is no need for extra index updates.
|
360
|
+
Also indexing might be broken during migrations because of the outdated schema.
|
361
|
+
|
362
|
+
Controller actions are wrapped with `:atomic` strategy with middleware just to reduce amount of index update requests inside actions.
|
363
|
+
|
364
|
+
It is also a good idea to set up `:bypass` strategy inside your test suite and import objects manually only when needed, plus use `Chewy.massacre` when needed to flush test ES indexes before every example. This will allow to minimize unnecessary ES requests and reduce overhead.
|
365
|
+
|
366
|
+
|
367
|
+
```ruby
|
368
|
+
RSpec.configure do |config|
|
369
|
+
config.before(:suite) do
|
370
|
+
Chewy.strategy(:bypass)
|
371
|
+
end
|
372
|
+
end
|
373
|
+
```
|
374
|
+
|
280
375
|
### Index querying
|
281
376
|
|
282
377
|
```ruby
|
@@ -692,7 +787,7 @@ Chewy has notifing the following events:
|
|
692
787
|
{index: 30, delete: 5}
|
693
788
|
```
|
694
789
|
|
695
|
-
* `payload[:
|
790
|
+
* `payload[:errors]`: might not exists. Contains grouped errors with objects ids list:
|
696
791
|
|
697
792
|
```ruby
|
698
793
|
{index: {
|
@@ -709,26 +804,26 @@ To integrate with NewRelic you may use the following example source (config/init
|
|
709
804
|
|
710
805
|
```ruby
|
711
806
|
ActiveSupport::Notifications.subscribe('import_objects.chewy') do |name, start, finish, id, payload|
|
712
|
-
|
807
|
+
metric_name = "Database/ElasticSearch/import"
|
713
808
|
duration = (finish - start).to_f
|
714
809
|
logged = "#{payload[:type]} #{payload[:import].to_a.map{ |i| i.join(':') }.join(', ')}"
|
715
810
|
|
716
|
-
self.class.trace_execution_scoped([
|
811
|
+
self.class.trace_execution_scoped([metric_name]) do
|
717
812
|
NewRelic::Agent.instance.transaction_sampler.notice_sql(logged, nil, duration)
|
718
|
-
NewRelic::Agent.instance.sql_sampler.notice_sql(logged,
|
719
|
-
NewRelic::Agent.
|
813
|
+
NewRelic::Agent.instance.sql_sampler.notice_sql(logged, metric_name, nil, duration)
|
814
|
+
NewRelic::Agent.record_metric(metric_name, duration)
|
720
815
|
end
|
721
816
|
end
|
722
817
|
|
723
818
|
ActiveSupport::Notifications.subscribe('search_query.chewy') do |name, start, finish, id, payload|
|
724
|
-
|
819
|
+
metric_name = "Database/ElasticSearch/search"
|
725
820
|
duration = (finish - start).to_f
|
726
|
-
logged = "#{payload[:index]} #{payload[:request]}"
|
821
|
+
logged = "#{payload[:type].presence || payload[:index]} #{payload[:request]}"
|
727
822
|
|
728
|
-
self.class.trace_execution_scoped([
|
823
|
+
self.class.trace_execution_scoped([metric_name]) do
|
729
824
|
NewRelic::Agent.instance.transaction_sampler.notice_sql(logged, nil, duration)
|
730
|
-
NewRelic::Agent.instance.sql_sampler.notice_sql(logged,
|
731
|
-
NewRelic::Agent.
|
825
|
+
NewRelic::Agent.instance.sql_sampler.notice_sql(logged, metric_name, nil, duration)
|
826
|
+
NewRelic::Agent.record_metric(metric_name, duration)
|
732
827
|
end
|
733
828
|
end
|
734
829
|
```
|