search_flip 2.2.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -29,7 +29,7 @@ module SearchFlip
29
29
 
30
30
  # Adds a post query string query to the criteria while using AND as the
31
31
  # default operator unless otherwise specified. Check out the
32
- # ElasticSearch docs for further details.
32
+ # Elasticsearch docs for further details.
33
33
  #
34
34
  # @example
35
35
  # CommentIndex.aggregate(:user_id).post_search("message:hello OR message:worl*")
@@ -201,7 +201,7 @@ module SearchFlip
201
201
  # Adds a post range filter to the criteria without being forced to specify
202
202
  # the left and right end of the range, such that you can eg simply specify
203
203
  # lt, lte, gt and gte. For fully specified ranges, you can easily use
204
- # #post_where, etc. Check out the ElasticSearch docs for further details
204
+ # #post_where, etc. Check out the Elasticsearch docs for further details
205
205
  # regarding the range filter.
206
206
  #
207
207
  # @example
@@ -11,14 +11,14 @@ module SearchFlip
11
11
  # @api private
12
12
  #
13
13
  # Initializes a new response object for the provided criteria and raw
14
- # ElasticSearch response.
14
+ # Elasticsearch response.
15
15
 
16
16
  def initialize(criteria, response)
17
17
  self.criteria = criteria
18
18
  self.response = response
19
19
  end
20
20
 
21
- # Returns the raw response, ie a hash derived from the ElasticSearch JSON
21
+ # Returns the raw response, ie a hash derived from the Elasticsearch JSON
22
22
  # response.
23
23
  #
24
24
  # @example
@@ -198,25 +198,25 @@ module SearchFlip
198
198
  end
199
199
  end
200
200
 
201
- # Returns the hits returned by ElasticSearch.
201
+ # Returns the hits returned by Elasticsearch.
202
202
  #
203
203
  # @example
204
204
  # CommentIndex.search("hello world").hits
205
205
  # # => {"total"=>3, "max_score"=>2.34, "hits"=>[{...}, ...]}
206
206
  #
207
- # @return [Hash] The hits returned by ElasticSearch
207
+ # @return [Hash] The hits returned by Elasticsearch
208
208
 
209
209
  def hits
210
210
  response["hits"]
211
211
  end
212
212
 
213
- # Returns the scroll id returned by ElasticSearch, that can be used in the
213
+ # Returns the scroll id returned by Elasticsearch, that can be used in the
214
214
  # following request to fetch the next batch of records.
215
215
  #
216
216
  # @example
217
217
  # CommentIndex.scroll(timeout: "1m").scroll_id #=> "cXVlcnlUaGVuRmV0Y2..."
218
218
  #
219
- # @return [String] The scroll id returned by ElasticSearch
219
+ # @return [String] The scroll id returned by Elasticsearch
220
220
 
221
221
  def scroll_id
222
222
  response["_scroll_id"]
@@ -224,7 +224,7 @@ module SearchFlip
224
224
 
225
225
  # Returns the database records, usually ActiveRecord objects, depending on
226
226
  # the ORM you're using. The records are sorted using the order returned by
227
- # ElasticSearch.
227
+ # Elasticsearch.
228
228
  #
229
229
  # @example
230
230
  # CommentIndex.search("hello world").records # => [#<Comment ...>, ...]
@@ -240,7 +240,7 @@ module SearchFlip
240
240
  end
241
241
 
242
242
  # Builds and returns a scope for the array of ids in the current result set
243
- # returned by ElasticSearch, including the eager load, preload and includes
243
+ # returned by Elasticsearch, including the eager load, preload and includes
244
244
  # associations, if specified. A scope is eg an ActiveRecord::Relation,
245
245
  # depending on the ORM you're using.
246
246
  #
@@ -259,7 +259,7 @@ module SearchFlip
259
259
  res
260
260
  end
261
261
 
262
- # Returns the array of ids returned by ElasticSearch for the current result
262
+ # Returns the array of ids returned by Elasticsearch for the current result
263
263
  # set, ie the ids listed in the hits section of the response.
264
264
  #
265
265
  # @example
@@ -273,19 +273,19 @@ module SearchFlip
273
273
 
274
274
  def_delegators :ids, :size, :count, :length
275
275
 
276
- # Returns the response time in milliseconds of ElasticSearch specified in
276
+ # Returns the response time in milliseconds of Elasticsearch specified in
277
277
  # the took info of the response.
278
278
  #
279
279
  # @example
280
280
  # CommentIndex.match_all.took # => 6
281
281
  #
282
- # @return [Fixnum] The ElasticSearch response time in milliseconds
282
+ # @return [Fixnum] The Elasticsearch response time in milliseconds
283
283
 
284
284
  def took
285
285
  response["took"]
286
286
  end
287
287
 
288
- # Returns a single or all aggregations returned by ElasticSearch, depending
288
+ # Returns a single or all aggregations returned by Elasticsearch, depending
289
289
  # on whether or not a name is specified. If no name is specified, the raw
290
290
  # aggregation hash is simply returned. Contrary, if a name is specified,
291
291
  # only this aggregation is returned. Moreover, if a name is specified and
@@ -300,7 +300,7 @@ module SearchFlip
300
300
  # CommentIndex.aggregate(:user_id).aggregations(:user_id)
301
301
  # # => {4922=>1129, ...}
302
302
  #
303
- # @return [Hash] Specific or all aggregations returned by ElasticSearch
303
+ # @return [Hash] Specific or all aggregations returned by Elasticsearch
304
304
 
305
305
  def aggregations(name = nil)
306
306
  return response["aggregations"] || {} unless name
@@ -1,5 +1,5 @@
1
1
 
2
2
  module SearchFlip
3
- VERSION = "2.2.0"
3
+ VERSION = "2.3.0"
4
4
  end
5
5
 
data/search_flip.gemspec CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
9
9
  spec.version = SearchFlip::VERSION
10
10
  spec.authors = ["Benjamin Vetter"]
11
11
  spec.email = ["vetter@flakks.com"]
12
- spec.description = %q{Compositional EasticSearch client library}
13
- spec.summary = %q{Powerful ElasticSearch client library to easily build complex queries}
12
+ spec.description = %q{Full-Featured Elasticsearch Ruby Client with a Chainable DSL}
13
+ spec.summary = %q{Full-Featured Elasticsearch Ruby Client with a Chainable DSL}
14
14
  spec.homepage = "https://github.com/mrkamel/search_flip"
15
15
  spec.license = "MIT"
16
16
 
@@ -30,7 +30,7 @@ Gem::Specification.new do |spec|
30
30
  spec.add_development_dependency "factory_bot"
31
31
  spec.add_development_dependency "rake"
32
32
  spec.add_development_dependency "rspec"
33
- spec.add_development_dependency "sqlite3", "~> 1.3.6"
33
+ spec.add_development_dependency "sqlite3"
34
34
  spec.add_development_dependency "timecop"
35
35
  spec.add_development_dependency "webmock"
36
36
 
@@ -36,7 +36,7 @@ RSpec.describe SearchFlip::Criteria do
36
36
  methods = [
37
37
  :profile_value, :failsafe_value, :terminate_after_value, :timeout_value,
38
38
  :offset_value, :limit_value, :scroll_args, :source_value, :preference_value,
39
- :search_type_value, :routing_value, :track_total_hits_value
39
+ :search_type_value, :routing_value, :track_total_hits_value, :explain_value
40
40
  ]
41
41
 
42
42
  methods.each do |method|
@@ -259,6 +259,54 @@ RSpec.describe SearchFlip::Criteria do
259
259
  end
260
260
  end
261
261
 
262
+ describe "#must" do
263
+ it "sets up the constraints correctly and is chainable" do
264
+ product1 = create(:product, price: 100, category: "category1")
265
+ product2 = create(:product, price: 200, category: "category2")
266
+ product3 = create(:product, price: 300, category: "category1")
267
+
268
+ ProductIndex.import [product1, product2, product3]
269
+
270
+ query1 = ProductIndex.must(range: { price: { gte: 100, lte: 200 } })
271
+ query2 = query1.must(term: { category: "category1" })
272
+
273
+ expect(query1.records.to_set).to eq([product1, product2].to_set)
274
+ expect(query2.records).to eq([product1])
275
+ end
276
+ end
277
+
278
+ describe "#must_not" do
279
+ it "sets up the constraints correctly and is chainable" do
280
+ product1 = create(:product, price: 100, category: "category1")
281
+ product2 = create(:product, price: 200, category: "category2")
282
+ product3 = create(:product, price: 300, category: "category1")
283
+
284
+ ProductIndex.import [product1, product2, product3]
285
+
286
+ query1 = ProductIndex.must_not(range: { price: { gt: 200, lte: 300 } })
287
+ query2 = query1.must_not(term: { category: "category2" })
288
+
289
+ expect(query1.records.to_set).to eq([product1, product2].to_set)
290
+ expect(query2.records).to eq([product1])
291
+ end
292
+ end
293
+
294
+ describe "#should" do
295
+ it "sets up the constraints correctly and is chainable" do
296
+ product1 = create(:product, price: 100, category: "category1")
297
+ product2 = create(:product, price: 200, category: "category2")
298
+ product3 = create(:product, price: 300, category: "category1")
299
+
300
+ ProductIndex.import [product1, product2, product3]
301
+
302
+ query1 = ProductIndex.should(range: { price: { gte: 100, lt: 200 } })
303
+ query2 = query1.should(term: { category: "category2" })
304
+
305
+ expect(query1.records.to_set).to eq([product1].to_set)
306
+ expect(query2.records.to_set).to eq([product1, product2].to_set)
307
+ end
308
+ end
309
+
262
310
  describe "#range" do
263
311
  it "sets up the constraints correctly and is chainable" do
264
312
  product1 = create(:product, price: 100)
@@ -1035,6 +1083,15 @@ RSpec.describe SearchFlip::Criteria do
1035
1083
  end
1036
1084
  end
1037
1085
 
1086
+ describe "#explain" do
1087
+ it "returns the explaination" do
1088
+ ProductIndex.import create(:product)
1089
+
1090
+ query = ProductIndex.match_all.explain(true)
1091
+ expect(query.results.first._hit.key?(:_explanation)).to eq(true)
1092
+ end
1093
+ end
1094
+
1038
1095
  describe "#custom" do
1039
1096
  it "adds a custom entry to the request" do
1040
1097
  request = ProductIndex.custom(custom_key: "custom_value").request
@@ -15,7 +15,7 @@ RSpec.describe SearchFlip::Index do
15
15
  :total_entries, :total_count, :terminate_after, :timeout, :records, :results,
16
16
  :should, :should_not, :must, :must_not, :find_each_result,
17
17
  :find_results_in_batches, :preference, :search_type, :routing,
18
- :track_total_hits
18
+ :track_total_hits, :explain
19
19
  ]
20
20
 
21
21
  methods.each do |method|
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: search_flip
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin Vetter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-20 00:00:00.000000000 Z
11
+ date: 2019-08-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -84,16 +84,16 @@ dependencies:
84
84
  name: sqlite3
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
- version: 1.3.6
89
+ version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - "~>"
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
- version: 1.3.6
96
+ version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: timecop
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -164,7 +164,7 @@ dependencies:
164
164
  - - ">="
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
- description: Compositional EasticSearch client library
167
+ description: Full-Featured Elasticsearch Ruby Client with a Chainable DSL
168
168
  email:
169
169
  - vetter@flakks.com
170
170
  executables: []
@@ -199,7 +199,6 @@ files:
199
199
  - lib/search_flip/result.rb
200
200
  - lib/search_flip/to_json.rb
201
201
  - lib/search_flip/version.rb
202
- - logo.svg
203
202
  - search_flip.gemspec
204
203
  - spec/delegate_matcher.rb
205
204
  - spec/search_flip/aggregation_spec.rb
@@ -234,11 +233,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
234
233
  - !ruby/object:Gem::Version
235
234
  version: '0'
236
235
  requirements: []
237
- rubyforge_project:
238
- rubygems_version: 2.7.3
236
+ rubygems_version: 3.0.3
239
237
  signing_key:
240
238
  specification_version: 4
241
- summary: Powerful ElasticSearch client library to easily build complex queries
239
+ summary: Full-Featured Elasticsearch Ruby Client with a Chainable DSL
242
240
  test_files:
243
241
  - spec/delegate_matcher.rb
244
242
  - spec/search_flip/aggregation_spec.rb
data/logo.svg DELETED
@@ -1,96 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
- <!-- Generated by IcoMoon.io -->
3
-
4
- <svg
5
- xmlns:dc="http://purl.org/dc/elements/1.1/"
6
- xmlns:cc="http://creativecommons.org/ns#"
7
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8
- xmlns:svg="http://www.w3.org/2000/svg"
9
- xmlns="http://www.w3.org/2000/svg"
10
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
11
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
12
- version="1.1"
13
- width="300"
14
- height="50"
15
- viewBox="0 0 299.99998 50"
16
- id="svg4869"
17
- sodipodi:docname="logo.svg"
18
- inkscape:export-filename="/home/hkf/projects/search_flip/logo.png"
19
- inkscape:export-xdpi="299.34824"
20
- inkscape:export-ydpi="299.34824"
21
- inkscape:version="0.92.1 r15371">
22
- <metadata
23
- id="metadata4875">
24
- <rdf:RDF>
25
- <cc:Work
26
- rdf:about="">
27
- <dc:format>image/svg+xml</dc:format>
28
- <dc:type
29
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
30
- <dc:title>arrow-long-up</dc:title>
31
- </cc:Work>
32
- </rdf:RDF>
33
- </metadata>
34
- <defs
35
- id="defs4873" />
36
- <sodipodi:namedview
37
- pagecolor="#ffffff"
38
- bordercolor="#666666"
39
- borderopacity="1"
40
- objecttolerance="10"
41
- gridtolerance="10"
42
- guidetolerance="10"
43
- inkscape:pageopacity="0"
44
- inkscape:pageshadow="2"
45
- inkscape:window-width="1920"
46
- inkscape:window-height="971"
47
- id="namedview4871"
48
- showgrid="false"
49
- fit-margin-top="0"
50
- fit-margin-left="0"
51
- fit-margin-right="0"
52
- fit-margin-bottom="0"
53
- inkscape:zoom="2.085965"
54
- inkscape:cx="91.987216"
55
- inkscape:cy="-41.606043"
56
- inkscape:window-x="0"
57
- inkscape:window-y="31"
58
- inkscape:window-maximized="1"
59
- inkscape:current-layer="svg4869" />
60
- <title
61
- id="title4865">arrow-long-up</title>
62
- <path
63
- d="M 39.922489,4.151999 36.230955,18.361869 32.37339,14.504302 10.209748,36.667943 7.4576271,33.915823 29.621268,11.75218 25.712619,7.843531 Z"
64
- id="path4867"
65
- inkscape:connector-curvature="0"
66
- style="stroke-width:1.80568123"
67
- inkscape:export-xdpi="325.4834"
68
- inkscape:export-ydpi="325.4834"
69
- sodipodi:nodetypes="cccccccc"
70
- inkscape:export-filename="/home/hkf/projects/search_flip/text4908.png" />
71
- <path
72
- d="M 17.625202,45.376517 31.473864,41.323778 27.948317,37.696072 50.111962,15.532428 47.418207,12.940838 25.254566,35.10448 21.677941,31.527854 Z"
73
- id="path4867-7"
74
- inkscape:connector-curvature="0"
75
- style="stroke-width:1.74257004"
76
- inkscape:export-xdpi="325.4834"
77
- inkscape:export-ydpi="325.4834"
78
- sodipodi:nodetypes="cccccccc"
79
- inkscape:export-filename="/home/hkf/projects/search_flip/text4908.png" />
80
- <text
81
- xml:space="preserve"
82
- style="font-style:normal;font-weight:normal;font-size:96.44345093px;line-height:1.25;font-family:sans-serif;letter-spacing:-0.65099335px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.41108632"
83
- x="59.037937"
84
- y="37.501484"
85
- id="text4908"
86
- inkscape:export-filename="/home/hkf/projects/search_flip/text4908.png"
87
- inkscape:export-xdpi="325.4834"
88
- inkscape:export-ydpi="325.4834"
89
- inkscape:transform-center-x="-2.0432889"
90
- inkscape:transform-center-y="-9.8078108"><tspan
91
- sodipodi:role="line"
92
- id="tspan4906"
93
- x="59.037937"
94
- y="37.501484"
95
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:51.43650818px;line-height:6;font-family:'times new roman';-inkscape-font-specification:'times new roman, ';letter-spacing:0px;word-spacing:-19.48158455px;stroke-width:2.41108632">search_flip</tspan></text>
96
- </svg>