es-elasticity 0.4.5 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b30428e6913d8edd82b5db7963dce7e372ea2f27
4
- data.tar.gz: 213ba5a4a695cc18ac1c16f1c050988de0ec28b5
3
+ metadata.gz: 964aa0b0955363219b5b3258cfcf7341c9eccae7
4
+ data.tar.gz: e6379e81e8abba1a895a02e9d915f440e627f47f
5
5
  SHA512:
6
- metadata.gz: 48f09521d34b7098daf93748d5ccd9423c34138389d98e0cd42767a9a7e2713dcf0c3923ea51c2dbfb7b455d2d776ae9167ed7c68ea4b84bfca551d9e44b0e24
7
- data.tar.gz: 6c1596b4b9a3d7f3ceae0bc52a5ff281d2102530af49f12b67f5524596ac95bff6783154ab8db260b6898eb9543f5ac8a7427c1b16680854d13d1b2d9b43f5e4
6
+ metadata.gz: ec06b056b633344895a0d045df11f365854e398bc7f10c109c4c2cfe827ee16a17ca73a41570faf116ea0d4dbd55274522a76ec94c88cf95a261f61edf56535a
7
+ data.tar.gz: 221d4232fbc52a63fd16bc309c4474295817ecb9133b21b742004e16a6ee4200f966290d8ad5e338bfb5d2abb9f808d40a4902bc727231366d645c2895ef011f
@@ -1,5 +1,6 @@
1
1
  module Elasticity
2
2
  class MultiSearch
3
+
3
4
  def initialize
4
5
  @searches = {}
5
6
  @mappers = {}
@@ -23,12 +24,15 @@ module Elasticity
23
24
  end
24
25
 
25
26
  def [](name)
26
- @results ||= fetch
27
- @results[name]
27
+ results_collection[name]
28
28
  end
29
29
 
30
30
  private
31
31
 
32
+ def results_collection
33
+ @results_collection ||= fetch
34
+ end
35
+
32
36
  def fetch
33
37
  bodies = @searches.values.map do |hsh|
34
38
  hsh[:search_definition].to_msearch_args
@@ -37,7 +41,6 @@ module Elasticity
37
41
  response = ActiveSupport::Notifications.instrument("multi_search.elasticity", args: { body: bodies }) do
38
42
  Elasticity.config.client.msearch(body: bodies.map(&:dup))
39
43
  end
40
-
41
44
  results = {}
42
45
 
43
46
  @searches.keys.each_with_index do |name, idx|
@@ -46,9 +49,9 @@ module Elasticity
46
49
 
47
50
  results[name] = case
48
51
  when search[:documents]
49
- resp["hits"]["hits"].map { |hit| search[:documents].map_hit(hit) }
52
+ Search::Results.new(resp, search[:search_definition].body, search[:documents].method(:map_hit))
50
53
  when search[:active_records]
51
- Search::ActiveRecordProxy.from_hits(search[:active_records], resp["hits"]["hits"])
54
+ Search::ActiveRecordProxy.map_response(search[:active_records], search[:search_definition].body, resp)
52
55
  end
53
56
  end
54
57
 
@@ -84,12 +84,11 @@ module Elasticity
84
84
  class LazySearch
85
85
  include Enumerable
86
86
 
87
- delegate :each, :size, :length, :[], :+, :-, :&, :|, to: :search_results
87
+ delegate :each, :size, :length, :[], :+, :-, :&, :|, :total, :per_page,
88
+ :total_pages, :current_page, to: :search_results
88
89
 
89
90
  attr_accessor :search_definition
90
91
 
91
- DEFAULT_SIZE = 10
92
-
93
92
  def initialize(client, search_definition, &mapper)
94
93
  @client = client
95
94
  @search_definition = search_definition
@@ -104,10 +103,6 @@ module Elasticity
104
103
  empty?
105
104
  end
106
105
 
107
- def total
108
- response["hits"]["total"]
109
- end
110
-
111
106
  def aggregations
112
107
  response["aggregations"] ||= {}
113
108
  end
@@ -121,31 +116,7 @@ module Elasticity
121
116
  end
122
117
 
123
118
  def search_results
124
- return @search_results if defined?(@search_results)
125
-
126
- hits = response["hits"]["hits"]
127
-
128
- @search_results = if @mapper.nil?
129
- hits
130
- else
131
- hits.map { |hit| @mapper.(hit) }
132
- end
133
- end
134
-
135
- # for pagination
136
- def per_page
137
- @search_definition.body[:size] || DEFAULT_SIZE
138
- end
139
-
140
- # for pagination
141
- def total_pages
142
- (total.to_f / per_page.to_f).ceil
143
- end
144
-
145
- # for pagination
146
- def current_page
147
- return 1 if @search_definition.body[:from].nil?
148
- @search_definition.body[:from] / per_page + 1
119
+ @search_results ||= Search::Results.new(response, @search_definition.body, @mapper)
149
120
  end
150
121
 
151
122
  private
@@ -199,10 +170,9 @@ module Elasticity
199
170
 
200
171
  loop do
201
172
  response = @client.scroll(scroll_id: response["_scroll_id"], scroll: @scroll)
202
- hits = response["hits"]["hits"]
203
- break if hits.empty?
173
+ break if response["hits"]["hits"].empty?
204
174
 
205
- y << hits.map { |hit| @mapper.(hit) }
175
+ y << Search::Results.new(response, @search_definition.body, @mapper)
206
176
  end
207
177
  end
208
178
  end
@@ -216,21 +186,27 @@ module Elasticity
216
186
  end
217
187
 
218
188
  class ActiveRecordProxy
219
- def self.from_hits(relation, hits)
220
- ids = hits.map { |hit| hit["_id"] }
189
+ def self.map_response(relation, body, response)
190
+ ids = response["hits"]["hits"].map { |hit| hit["_id"] }
221
191
 
222
192
  if ids.any?
223
193
  id_col = "#{relation.connection.quote_column_name(relation.table_name)}.#{relation.connection.quote_column_name(relation.klass.primary_key)}"
224
194
  id_vals = ids.map { |id| relation.connection.quote(id) }
225
- relation.where("#{id_col} IN (?)", ids).order("FIELD(#{id_col}, #{id_vals.join(',')})")
195
+ Relation.new(relation.where("#{id_col} IN (?)", ids).order("FIELD(#{id_col}, #{id_vals.join(',')})"), body, response)
226
196
  else
227
- relation.none
197
+ Relation.new(relation.none, body, response)
228
198
  end
229
199
  end
230
200
 
231
201
  class Relation < ActiveSupport::ProxyObject
232
- def initialize(relation)
202
+
203
+ delegate :total, :per_page, :total_pages, :current_page, to: :@results
204
+
205
+ def initialize(relation, search_definition, response)
233
206
  @relation = relation
207
+ @search_definition = search_definition
208
+ @response = response
209
+ @results = Results.new(response, search_definition)
234
210
  end
235
211
 
236
212
  def method_missing(name, *args, &block)
@@ -251,7 +227,7 @@ module Elasticity
251
227
  def initialize(client, search_definition, relation)
252
228
  @client = client
253
229
  @search_definition = search_definition.update(_source: false)
254
- @relation = Relation.new(relation)
230
+ @relation = relation
255
231
  end
256
232
 
257
233
  def metadata
@@ -278,7 +254,7 @@ module Elasticity
278
254
 
279
255
  def filtered_relation
280
256
  return @filtered_relation if defined?(@filtered_relation)
281
- @filtered_relation = ActiveRecordProxy.from_hits(@relation, response["hits"]["hits"])
257
+ @filtered_relation = ActiveRecordProxy.map_response(@relation, @search_definition.body, response)
282
258
  end
283
259
  end
284
260
 
@@ -302,5 +278,51 @@ module Elasticity
302
278
  documents.public_send(method_name, *args, &block)
303
279
  end
304
280
  end
281
+
282
+ class Results < ActiveSupport::ProxyObject
283
+ include ::Enumerable
284
+
285
+ delegate :each, :size, :length, :[], :+, :-, :&, :|, to: :@documents
286
+
287
+ DEFAULT_SIZE = 10
288
+
289
+ def initialize(response, body, mapper = nil)
290
+ @response = response
291
+ @body = body
292
+ @documents = if mapper.nil?
293
+ @response["hits"]["hits"]
294
+ else
295
+ @response["hits"]["hits"].map { |hit| mapper.(hit) }
296
+ end
297
+ end
298
+
299
+ def method_missing(name, *args, &block)
300
+ @documents.public_send(name, *args, &block)
301
+ end
302
+
303
+ def each(&block)
304
+ @documents.each(&block)
305
+ end
306
+
307
+ def total
308
+ @response["hits"]["total"]
309
+ end
310
+
311
+ # for pagination
312
+ def per_page
313
+ @body[:size] || DEFAULT_SIZE
314
+ end
315
+
316
+ # for pagination
317
+ def total_pages
318
+ (total.to_f / per_page.to_f).ceil
319
+ end
320
+
321
+ # for pagination
322
+ def current_page
323
+ return 1 if @body[:from].nil?
324
+ @body[:from] / per_page + 1
325
+ end
326
+ end
305
327
  end
306
328
  end
@@ -1,3 +1,3 @@
1
1
  module Elasticity
2
- VERSION = "0.4.5"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -25,6 +25,7 @@ RSpec.describe "Persistence", elasticsearch: true do
25
25
 
26
26
  before do
27
27
  subject.recreate_index
28
+ @elastic_search_client.cluster.health wait_for_status: 'yellow'
28
29
  end
29
30
 
30
31
  after do
@@ -31,15 +31,18 @@ RSpec.describe Elasticity::MultiSearch do
31
31
  end
32
32
 
33
33
  it "performs multi search" do
34
- subject.add(:first, Elasticity::Search::Facade.new(client, Elasticity::Search::Definition.new("index_first", "document_first", { search: :first })), documents: klass)
34
+ subject.add(:first, Elasticity::Search::Facade.new(client, Elasticity::Search::Definition.new("index_first", "document_first", { search: :first, size: 2 })), documents: klass)
35
35
  subject.add(:second, Elasticity::Search::Facade.new(client, Elasticity::Search::Definition.new("index_second", "document_second", { search: :second })), documents: klass)
36
36
 
37
37
  expect(Elasticity.config.client).to receive(:msearch).with(body: [
38
- { index: "index_first", type: "document_first", search: { search: :first } },
38
+ { index: "index_first", type: "document_first", search: { search: :first, size: 2 } },
39
39
  { index: "index_second", type: "document_second", search: { search: :second } },
40
40
  ]).and_return(response)
41
41
 
42
- expect(Array(subject[:first])). to eq [klass.new(_id: 1, name: "foo"), klass.new(_id: 2, name: "bar")]
43
- expect(Array(subject[:second])). to eq [klass.new(_id: 3, name: "baz")]
42
+ expect(Array(subject[:first])).to eq [klass.new(_id: 1, name: "foo"), klass.new(_id: 2, name: "bar")]
43
+ expect(Array(subject[:second])).to eq [klass.new(_id: 3, name: "baz")]
44
+ expect(subject[:first].total).to eq 2
45
+ expect(subject[:first].total_pages).to eq 1
46
+ expect(subject[:first].current_page).to eq 1
44
47
  end
45
48
  end
@@ -132,6 +132,7 @@ RSpec.describe "Search" do
132
132
  klass: double(:klass, primary_key: "id"),
133
133
  to_sql: "SELECT * FROM table_name WHERE id IN (1)"
134
134
  )
135
+
135
136
  allow(relation.connection).to receive(:quote_column_name) { |name| name }
136
137
  allow(relation.connection).to receive(:quote) { |name| name }
137
138
 
@@ -167,7 +168,7 @@ RSpec.describe "Search" do
167
168
  index: index_name,
168
169
  type: document_type,
169
170
  body: { size: 14, from: 25, filter: {} }
170
- ).and_return({ "hits" => { "total" => 112 } })
171
+ ).and_return({ "hits" => { "total" => 112, "hits" => [] } })
171
172
  docs = subject.documents(mapper)
172
173
 
173
174
  expect(docs.per_page).to eq(14)
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.4.5
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Kochenburger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-29 00:00:00.000000000 Z
11
+ date: 2016-02-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -230,7 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
230
230
  version: '0'
231
231
  requirements: []
232
232
  rubyforge_project:
233
- rubygems_version: 2.4.5.1
233
+ rubygems_version: 2.4.5
234
234
  signing_key:
235
235
  specification_version: 4
236
236
  summary: ActiveModel-based library for working with Elasticsearch
@@ -243,3 +243,4 @@ test_files:
243
243
  - spec/units/multi_search_spec.rb
244
244
  - spec/units/search_spec.rb
245
245
  - spec/units/strategies/single_index_spec.rb
246
+ has_rdoc: