es-elasticity 0.4.5 → 0.5.0

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: 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: