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 +4 -4
- data/lib/elasticity/multi_search.rb +8 -5
- data/lib/elasticity/search.rb +64 -42
- data/lib/elasticity/version.rb +1 -1
- data/spec/functional/persistence_spec.rb +1 -0
- data/spec/units/multi_search_spec.rb +7 -4
- data/spec/units/search_spec.rb +2 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 964aa0b0955363219b5b3258cfcf7341c9eccae7
|
4
|
+
data.tar.gz: e6379e81e8abba1a895a02e9d915f440e627f47f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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[
|
52
|
+
Search::Results.new(resp, search[:search_definition].body, search[:documents].method(:map_hit))
|
50
53
|
when search[:active_records]
|
51
|
-
Search::ActiveRecordProxy.
|
54
|
+
Search::ActiveRecordProxy.map_response(search[:active_records], search[:search_definition].body, resp)
|
52
55
|
end
|
53
56
|
end
|
54
57
|
|
data/lib/elasticity/search.rb
CHANGED
@@ -84,12 +84,11 @@ module Elasticity
|
|
84
84
|
class LazySearch
|
85
85
|
include Enumerable
|
86
86
|
|
87
|
-
delegate :each, :size, :length, :[], :+, :-, :&, :|,
|
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
|
-
|
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
|
-
|
203
|
-
break if hits.empty?
|
173
|
+
break if response["hits"]["hits"].empty?
|
204
174
|
|
205
|
-
y <<
|
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.
|
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
|
-
|
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 =
|
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.
|
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
|
data/lib/elasticity/version.rb
CHANGED
@@ -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])).
|
43
|
-
expect(Array(subject[:second])).
|
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
|
data/spec/units/search_spec.rb
CHANGED
@@ -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
|
+
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-
|
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
|
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:
|