es-elasticity 0.9.0 → 0.11.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e309966bac2144c3c9cb5f0b224558d4bb025cf3
4
- data.tar.gz: 67bbe2abe0812300f3481686ee3a3429c387ae26
3
+ metadata.gz: 11dddda9376573d12d8d6c0db18342c7a242199a
4
+ data.tar.gz: 2613b868ae0ca372149fa84724790ade9bbca2a2
5
5
  SHA512:
6
- metadata.gz: befdfdb3ef94fadc1637ef6597092b9a3165051a22a832341bc9de9b02ee2281d835419fb997390202e4514c11573d67ab6b994a2720afd2cb0c32f847bf7e75
7
- data.tar.gz: 8fba3aa740454246d3a1f308adf809b5fc804a5c06e97d6d853c8a93d69897341a2797964583eba64f1dc281a5980251d4025ac73b90757ec82eefd926e5f757
6
+ metadata.gz: 13a78c3cbe8eb55a911d7b39d1a31e07329e4e3f809fde432ece6a12511db5e40422af47f3508938ec597579aef697a05622dc449670537b45b4ba64ee4b22e3
7
+ data.tar.gz: bcb01eb45bf67cf5dc2d6c0cfd7bb6ad00fc40167e5068da1e067d6a77f8f7d811b812b7de923fca134eea8ea28510114e9e1e235c9ff61b148a391e30a5f035
data/CHANGELOG CHANGED
@@ -1,3 +1,16 @@
1
+ v0.11.1
2
+ - support `action.destructive_requires_name` setting by being explict about which indices to delete
3
+
4
+ v0.11.0
5
+ - compatibilty with ES v6
6
+ - change mappings for 'index' to boolean. "string" type was replaced with "text"
7
+ - use "successful" from API response ('created' was removed)
8
+ - stringify keys for :mappings so clients can use symbol keys
9
+ v0.10.0
10
+ - update remap to removing fields from the mapping that are not explicitly
11
+ defined.
12
+ v0.9.1
13
+ - fix search enumerator, missing first result set
1
14
  v0.8.3
2
15
  - fix remap method to use the scan api properly.
3
16
  v0.8.2
data/Gemfile CHANGED
@@ -3,4 +3,4 @@ source 'https://rubygems.org'
3
3
  # Specify your gem's dependencies in elasticity.gemspec
4
4
  gemspec
5
5
 
6
- gem "elasticsearch", "5.0.3"
6
+ gem "elasticsearch", "5.0.4"
data/README.md CHANGED
@@ -80,7 +80,7 @@ class Search::User < Elasticity::Document
80
80
  def self.adults
81
81
  date = Date.today - 21.years
82
82
 
83
- # This is the query that will be submited to ES, same format ES would
83
+ # This is the query that will be submitted to ES, same format ES would
84
84
  # expect, translated to a Ruby hash, note the pagination params.
85
85
  body = {
86
86
  from: 0,
@@ -159,7 +159,7 @@ The search object implements `Enumerable`, so it can be treated as a collection:
159
159
  ```ruby
160
160
  # Get the search object, which is an instance of `Elasticity::DocumentSearchProxy`.
161
161
  # Search is not performed until data is accessed.
162
- adults = User.adults
162
+ adults = Search::User.adults
163
163
 
164
164
  # Iterating over the results will trigger the query
165
165
  adults.each do |user|
@@ -203,7 +203,7 @@ Using this feature is very easy and very similar to traditional documents. The o
203
203
  class Search::User < Elasticity::SegmentedDocument
204
204
  configure do |c|
205
205
  # Defines how the index will be named, the final name
206
- # will depend on the stragy being used.
206
+ # will depend on the strategy being used.
207
207
  c.index_base_name = "users"
208
208
 
209
209
  # Defines the document type that this class represents.
@@ -227,7 +227,7 @@ class Search::User < Elasticity::SegmentedDocument
227
227
  def self.adults
228
228
  date = Date.today - 21.years
229
229
 
230
- # This is the query that will be submited to ES, same format ES would
230
+ # This is the query that will be submitted to ES, same format ES would
231
231
  # expect, translated to a Ruby hash, note the pagination params.
232
232
  body = {
233
233
  from: 0,
@@ -283,7 +283,7 @@ Strategies define how index creation and index operation happens on the lower le
283
283
 
284
284
  The single-index strategy is the most straightforward one. It causes one index to be created and any operation will be performed directly on that index. It's very simple but it has the downside of being a lot harder to update existing mapping since you'll have to drop the index and recreate from scratch.
285
285
 
286
- The alias-index strategy is a bit more complex but it allows for seameless hot remapping. It works by creating an index and two aliases pointing to that index. Any operation is performed on the aliases rather than the index, which allows hot swapping due atomic aliases updates.
286
+ The alias-index strategy is a bit more complex but it allows for seamless hot remapping. It works by creating an index and two aliases pointing to that index. Any operation is performed on the aliases rather than the index, which allows hot swapping due atomic aliases updates.
287
287
 
288
288
  Here is what it looks like:
289
289
 
@@ -297,7 +297,7 @@ Here is what it looks like:
297
297
  |_____________|
298
298
  ```
299
299
 
300
- Everytime a search operation is performed, it is performed against the main alias; when an update operation is performed, it is performed against the update alias; and, when a delete operation is performed, it is performed against the indexes pointed by both aliases.
300
+ Every time a search operation is performed, it is performed against the main alias; when an update operation is performed, it is performed against the update alias; and, when a delete operation is performed, it is performed against the indexes pointed by both aliases.
301
301
 
302
302
  When the mapping needs to change, a hot remapping can be performed by doing the following:
303
303
 
@@ -397,7 +397,7 @@ Search::User.adults.active_records(User.where(active: true))
397
397
  ```
398
398
 
399
399
  ## Upgrading from 0.7.0 to 0.8.0
400
- The default persistance strategy changed from SingleIndex to AliasIndex in version 0.8.0 Add the following to your Document configuration to maintain the legacy behaviour.
400
+ The default persistence strategy changed from SingleIndex to AliasIndex in version 0.8.0 Add the following to your Document configuration to maintain the legacy behaviour.
401
401
 
402
402
  ```ruby
403
403
  c.strategy = Elasticity::Strategies::SingleIndex
@@ -6,7 +6,7 @@ module Elasticity
6
6
  ].freeze
7
7
  VALIDATABLE_ATTRS = [:index_base_name, :document_type, :strategy].freeze
8
8
 
9
- attr_accessor *ATTRS
9
+ attr_accessor(*ATTRS)
10
10
 
11
11
  def initialize(elasticity_config, defaults = {})
12
12
  defaults.each do |k,v|
@@ -30,7 +30,7 @@ module Elasticity
30
30
  def definition
31
31
  return @definition if defined?(@definition)
32
32
  @definition = {
33
- settings: merge_settings, mappings: { @document_type => @mapping || {} }
33
+ settings: merge_settings, mappings: { @document_type => @mapping.nil? ? {} : @mapping.deep_stringify_keys }
34
34
  }
35
35
  subclasses.each do |doc_type, subclass|
36
36
  @definition[:mappings][doc_type] = subclass.constantize.mapping
@@ -164,7 +164,8 @@ module Elasticity
164
164
  def enumerator
165
165
  Enumerator.new do |y|
166
166
  response = search
167
-
167
+ # Push the first set of results before requesting the second set
168
+ y << Search::Results.new(response, @search_definition.body, @mapper)
168
169
  loop do
169
170
  response = @client.scroll(scroll_id: response["_scroll_id"], scroll: @scroll, body: { scroll_id: response["_scroll_id"] })
170
171
  break if response["hits"]["hits"].empty?
@@ -66,10 +66,17 @@ module Elasticity
66
66
  docs = @client.mget(body: { docs: id_docs }, refresh: true)["docs"]
67
67
  break if docs.empty?
68
68
 
69
+ # Modify document hashes to match the mapping definition so that legacy fields aren't added
70
+ defined_mapping_fields = index_def[:mappings][docs.first["_type"]]["properties"].keys
71
+
69
72
  # Move only documents that still exists on the old index, into the new index.
70
73
  ops = []
71
74
  docs.each do |doc|
72
- ops << { index: { _index: new_index, _type: doc["_type"], _id: doc["_id"], data: doc["_source"] } } if doc["found"]
75
+ if doc["found"]
76
+ legacy_fields = doc["_source"].keys - defined_mapping_fields
77
+ legacy_fields.each { |field| doc["_source"].delete(field) }
78
+ ops << { index: { _index: new_index, _type: doc["_type"], _id: doc["_id"], data: doc["_source"] } }
79
+ end
73
80
  end
74
81
 
75
82
  @client.bulk(body: ops)
@@ -179,7 +186,9 @@ module Elasticity
179
186
  end
180
187
 
181
188
  def delete
182
- @client.index_delete(index: "#{@main_alias}-*")
189
+ main_indexes.each do |index|
190
+ @client.index_delete(index: index)
191
+ end
183
192
  end
184
193
 
185
194
  def delete_if_defined
@@ -195,7 +204,7 @@ module Elasticity
195
204
  res = @client.index(index: @update_alias, type: type, id: id, body: attributes)
196
205
 
197
206
  if id = res["_id"]
198
- [id, res["created"]]
207
+ [id, res["_shards"] && res["_shards"]["successful"].to_i > 0]
199
208
  else
200
209
  raise IndexError.new(@update_alias, "failed to index document. Response: #{res.inspect}")
201
210
  end
@@ -1,3 +1,3 @@
1
1
  module Elasticity
2
- VERSION = "0.9.0"
2
+ VERSION = "0.11.1"
3
3
  end
@@ -16,8 +16,8 @@ RSpec.describe "Persistence", elasticsearch: true do
16
16
  c.strategy = Elasticity::Strategies::SingleIndex
17
17
 
18
18
  c.mapping = {
19
- properties: {
20
- name: { type: "string", index: "not_analyzed" },
19
+ "properties" => {
20
+ name: { type: "text", index: false },
21
21
  birthdate: { type: "date" },
22
22
  },
23
23
  }
@@ -85,7 +85,7 @@ RSpec.describe "Persistence", elasticsearch: true do
85
85
  c.index_base_name = "cats_and_dogs"
86
86
  c.strategy = Elasticity::Strategies::SingleIndex
87
87
  c.document_type = "cat"
88
- c.mapping = { properties: {
88
+ c.mapping = { "properties" => {
89
89
  name: { type: "string", index: "not_analyzed" },
90
90
  age: { type: "integer" }
91
91
  } }
@@ -103,7 +103,7 @@ RSpec.describe "Persistence", elasticsearch: true do
103
103
  c.index_base_name = "cats_and_dogs"
104
104
  c.strategy = Elasticity::Strategies::SingleIndex
105
105
  c.document_type = "dog"
106
- c.mapping = { properties: {
106
+ c.mapping = { "properties" => {
107
107
  name: { type: "string", index: "not_analyzed" },
108
108
  age: { type: "integer" },
109
109
  hungry: { type: "boolean" }
@@ -148,6 +148,7 @@ RSpec.describe "Persistence", elasticsearch: true do
148
148
  results = Animal.search({})
149
149
  expect(results.total).to eq 1
150
150
  expect(results.map(&:class)).to include(Dog)
151
+ expect(results.scan_documents.count).to eq(1)
151
152
  end
152
153
  end
153
154
 
@@ -164,7 +165,7 @@ RSpec.describe "Persistence", elasticsearch: true do
164
165
  c.strategy = Elasticity::Strategies::AliasIndex
165
166
 
166
167
  c.mapping = {
167
- properties: {
168
+ "properties" => {
168
169
  id: { type: "integer" },
169
170
  name: { type: "string", index: "not_analyzed" },
170
171
  birthdate: { type: "date" },
@@ -242,6 +243,50 @@ RSpec.describe "Persistence", elasticsearch: true do
242
243
  expect(results.total).to eq(2010)
243
244
  end
244
245
 
246
+ it "does not copy over fields not defined in the mapping" do
247
+ john = subject.new(_id: 1, id: 1, name: "John", birthdate: "1985-10-31", sort: ['john'])
248
+ mari = subject.new(_id: 2, id: 2, name: "Mari", birthdate: "1986-09-24", sort: ['mari'])
249
+
250
+ john.update
251
+ mari.update
252
+
253
+ subject.flush_index
254
+ results = subject.search({})
255
+ expect(results.first.birthdate).to be
256
+
257
+ # no birthdate
258
+ subject = Class.new(Elasticity::Document) do
259
+ def self.name
260
+ "SomeClass"
261
+ end
262
+
263
+ configure do |c|
264
+ c.index_base_name = "users"
265
+ c.document_type = "user"
266
+ c.strategy = Elasticity::Strategies::AliasIndex
267
+
268
+ c.mapping = {
269
+ "properties" => {
270
+ id: { type: "integer" },
271
+ name: { type: "string", index: "not_analyzed" },
272
+ },
273
+ }
274
+ end
275
+
276
+ attr_accessor :id, :name
277
+
278
+ def to_document
279
+ { id: id, name: name }
280
+ end
281
+ end
282
+
283
+ subject.remap!
284
+ subject.flush_index
285
+
286
+ results = subject.search({})
287
+ expect(results.first.respond_to?(:birthdate)).to be false
288
+ end
289
+
245
290
  it "recover from remap interrupts" do
246
291
  number_of_docs = 2000
247
292
  docs = number_of_docs.times.map do |i|
@@ -10,7 +10,7 @@ RSpec.describe "Segmented indexes", elasticsearch: true do
10
10
  c.document_type = "person"
11
11
  c.mapping = {
12
12
  properties: {
13
- name: { type: "string" },
13
+ name: { type: "text" },
14
14
  },
15
15
  }
16
16
  end
@@ -42,6 +42,7 @@ RSpec.describe "Segmented indexes", elasticsearch: true do
42
42
  ensure_index(seg)
43
43
 
44
44
  rodrigo = seg.new(name: "rodrigo")
45
+
45
46
  id, success = rodrigo.update
46
47
  expect(id).to be_kind_of(String)
47
48
  expect(success).to be true
@@ -49,12 +49,13 @@ RSpec.describe "Search" do
49
49
  end
50
50
 
51
51
  let :scan_response do
52
- { "_scroll_id" => "abc123", "hits" => { "total" => 2 } }
52
+ { "_scroll_id" => "abc123", "hits" => { "total" => 2, "hits" => [
53
+ { "_id" => 1, "_source" => { "name" => "foo" } }
54
+ ]}}
53
55
  end
54
56
 
55
57
  let :scroll_response do
56
- { "_scroll_id" => "abc456", "hits" => { "total" => 2, "hits" => [
57
- { "_id" => 1, "_source" => { "name" => "foo" } },
58
+ { "_scroll_id" => "abc456", "hits" => { "total" => 1, "hits" => [
58
59
  { "_id" => 2, "_source" => { "name" => "bar" } },
59
60
  ]}}
60
61
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: es-elasticity
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Kochenburger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-26 00:00:00.000000000 Z
11
+ date: 2018-05-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -260,7 +260,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
260
260
  version: '0'
261
261
  requirements: []
262
262
  rubyforge_project:
263
- rubygems_version: 2.6.13
263
+ rubygems_version: 2.6.14
264
264
  signing_key:
265
265
  specification_version: 4
266
266
  summary: ActiveModel-based library for working with Elasticsearch