search_flip 2.3.2 → 3.0.0.beta
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/.rubocop.yml +21 -21
- data/.travis.yml +3 -5
- data/CHANGELOG.md +21 -5
- data/Gemfile +0 -2
- data/README.md +36 -16
- data/Rakefile +0 -1
- data/UPDATING.md +91 -0
- data/lib/search_flip/aggregatable.rb +0 -2
- data/lib/search_flip/aggregation.rb +8 -17
- data/lib/search_flip/bulk.rb +1 -3
- data/lib/search_flip/config.rb +0 -2
- data/lib/search_flip/connection.rb +40 -13
- data/lib/search_flip/criteria.rb +38 -105
- data/lib/search_flip/exceptions.rb +0 -2
- data/lib/search_flip/filterable.rb +51 -38
- data/lib/search_flip/helper.rb +13 -0
- data/lib/search_flip/http_client.rb +1 -7
- data/lib/search_flip/index.rb +21 -4
- data/lib/search_flip/json.rb +0 -2
- data/lib/search_flip/model.rb +0 -2
- data/lib/search_flip/post_filterable.rb +31 -36
- data/lib/search_flip/response.rb +5 -7
- data/lib/search_flip/result.rb +0 -2
- data/lib/search_flip/to_json.rb +4 -6
- data/lib/search_flip/version.rb +1 -3
- data/lib/search_flip.rb +1 -3
- data/search_flip.gemspec +4 -5
- data/spec/delegate_matcher.rb +0 -2
- data/spec/search_flip/aggregation_spec.rb +3 -4
- data/spec/search_flip/bulk_spec.rb +24 -19
- data/spec/search_flip/connection_spec.rb +48 -7
- data/spec/search_flip/criteria_spec.rb +178 -24
- data/spec/search_flip/http_client_spec.rb +0 -1
- data/spec/search_flip/index_spec.rb +25 -13
- data/spec/search_flip/model_spec.rb +0 -1
- data/spec/search_flip/response_spec.rb +0 -4
- data/spec/search_flip/to_json_spec.rb +0 -1
- data/spec/spec_helper.rb +1 -3
- metadata +12 -10
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
module SearchFlip
|
3
2
|
# The SearchFlip::PostFilterable mixin provides chainable methods like
|
4
3
|
# #post_where, #post_exists, #post_range, etc to add and apply search
|
@@ -23,7 +22,7 @@ module SearchFlip
|
|
23
22
|
module PostFilterable
|
24
23
|
def self.included(base)
|
25
24
|
base.class_eval do
|
26
|
-
attr_accessor :
|
25
|
+
attr_accessor :post_must_values, :post_must_not_values, :post_filter_values
|
27
26
|
end
|
28
27
|
end
|
29
28
|
|
@@ -42,13 +41,9 @@ module SearchFlip
|
|
42
41
|
# @return [SearchFlip::Criteria] A newly created extended criteria
|
43
42
|
|
44
43
|
def post_search(q, options = {})
|
45
|
-
|
44
|
+
return self if q.to_s.strip.length.zero?
|
46
45
|
|
47
|
-
|
48
|
-
if q.to_s.strip.length > 0
|
49
|
-
criteria.post_search_values = (post_search_values || []) + [query_string: { query: q, default_operator: :AND }.merge(options)]
|
50
|
-
end
|
51
|
-
end
|
46
|
+
post_must(query_string: { query: q, default_operator: :AND }.merge(options))
|
52
47
|
end
|
53
48
|
|
54
49
|
# Adds post filters to your criteria for the supplied hash composed of
|
@@ -76,11 +71,13 @@ module SearchFlip
|
|
76
71
|
def post_where(hash)
|
77
72
|
hash.inject(fresh) do |memo, (key, value)|
|
78
73
|
if value.is_a?(Array)
|
79
|
-
memo.post_filter
|
74
|
+
memo.post_filter(terms: { key => value })
|
80
75
|
elsif value.is_a?(Range)
|
81
|
-
memo.post_filter
|
76
|
+
memo.post_filter(range: { key => { gte: value.min, lte: value.max } })
|
77
|
+
elsif value.nil?
|
78
|
+
memo.post_must_not(exists: { field: key })
|
82
79
|
else
|
83
|
-
memo.post_filter
|
80
|
+
memo.post_filter(term: { key => value })
|
84
81
|
end
|
85
82
|
end
|
86
83
|
end
|
@@ -109,11 +106,13 @@ module SearchFlip
|
|
109
106
|
def post_where_not(hash)
|
110
107
|
hash.inject(fresh) do |memo, (key, value)|
|
111
108
|
if value.is_a?(Array)
|
112
|
-
memo.post_must_not
|
109
|
+
memo.post_must_not(terms: { key => value })
|
113
110
|
elsif value.is_a?(Range)
|
114
|
-
memo.post_must_not
|
111
|
+
memo.post_must_not(range: { key => { gte: value.min, lte: value.max } })
|
112
|
+
elsif value.nil?
|
113
|
+
memo.post_filter(exists: { field: key })
|
115
114
|
else
|
116
|
-
memo.post_must_not
|
115
|
+
memo.post_must_not(term: { key => value })
|
117
116
|
end
|
118
117
|
end
|
119
118
|
end
|
@@ -132,9 +131,9 @@ module SearchFlip
|
|
132
131
|
#
|
133
132
|
# @return [SearchFlip::Criteria] A newly created extended criteria
|
134
133
|
|
135
|
-
def post_filter(
|
134
|
+
def post_filter(clause)
|
136
135
|
fresh.tap do |criteria|
|
137
|
-
criteria.post_filter_values = (post_filter_values || []) +
|
136
|
+
criteria.post_filter_values = (post_filter_values || []) + Helper.wrap_array(clause)
|
138
137
|
end
|
139
138
|
end
|
140
139
|
|
@@ -152,9 +151,9 @@ module SearchFlip
|
|
152
151
|
#
|
153
152
|
# @return [SearchFlip::Criteria] A newly created extended criteria
|
154
153
|
|
155
|
-
def post_must(
|
154
|
+
def post_must(clause)
|
156
155
|
fresh.tap do |criteria|
|
157
|
-
criteria.post_must_values = (post_must_values || []) +
|
156
|
+
criteria.post_must_values = (post_must_values || []) + Helper.wrap_array(clause)
|
158
157
|
end
|
159
158
|
end
|
160
159
|
|
@@ -172,30 +171,27 @@ module SearchFlip
|
|
172
171
|
#
|
173
172
|
# @return [SearchFlip::Criteria] A newly created extended criteria
|
174
173
|
|
175
|
-
def post_must_not(
|
174
|
+
def post_must_not(clause)
|
176
175
|
fresh.tap do |criteria|
|
177
|
-
criteria.post_must_not_values = (post_must_not_values || []) +
|
176
|
+
criteria.post_must_not_values = (post_must_not_values || []) + Helper.wrap_array(clause)
|
178
177
|
end
|
179
178
|
end
|
180
179
|
|
181
|
-
# Adds raw post should
|
180
|
+
# Adds a raw post should query to the criteria.
|
182
181
|
#
|
183
182
|
# @example Raw post term should query
|
184
183
|
# query = CommentIndex.aggregate("...")
|
185
|
-
# query = query.post_should(
|
184
|
+
# query = query.post_should([
|
185
|
+
# { term: { state: "new" } },
|
186
|
+
# { term: { state: "approved" } }
|
187
|
+
# ])
|
186
188
|
#
|
187
|
-
# @
|
188
|
-
# query = CommentIndex.aggregate("...")
|
189
|
-
# query = query.post_should(range: { created_at: { gte: Time.parse("2016-01-01") }})
|
190
|
-
#
|
191
|
-
# @param args [Array, Hash] The raw should query arguments
|
189
|
+
# @param clauses [Array] The raw should query arguments
|
192
190
|
#
|
193
191
|
# @return [SearchFlip::Criteria] A newly created extended criteria
|
194
192
|
|
195
|
-
def post_should(
|
196
|
-
|
197
|
-
criteria.post_should_values = (post_should_values || []) + args
|
198
|
-
end
|
193
|
+
def post_should(clause)
|
194
|
+
post_must(bool: { should: clause })
|
199
195
|
end
|
200
196
|
|
201
197
|
# Adds a post range filter to the criteria without being forced to specify
|
@@ -217,7 +213,7 @@ module SearchFlip
|
|
217
213
|
# @return [SearchFlip::Criteria] A newly created extended criteria
|
218
214
|
|
219
215
|
def post_range(field, options = {})
|
220
|
-
post_filter
|
216
|
+
post_filter(range: { field => options })
|
221
217
|
end
|
222
218
|
|
223
219
|
# Adds a post exists filter to the criteria, which selects all documents
|
@@ -232,10 +228,10 @@ module SearchFlip
|
|
232
228
|
# @return [SearchFlip::Criteria] A newly created extended criteria
|
233
229
|
|
234
230
|
def post_exists(field)
|
235
|
-
post_filter
|
231
|
+
post_filter(exists: { field: field })
|
236
232
|
end
|
237
233
|
|
238
|
-
# Adds a post exists not
|
234
|
+
# Adds a post exists not query to the criteria, which selects all documents
|
239
235
|
# for which the specified field's value is null.
|
240
236
|
#
|
241
237
|
# @example
|
@@ -247,8 +243,7 @@ module SearchFlip
|
|
247
243
|
# @return [SearchFlip::Criteria] A newly created extended criteria
|
248
244
|
|
249
245
|
def post_exists_not(field)
|
250
|
-
post_must_not
|
246
|
+
post_must_not(exists: { field: field })
|
251
247
|
end
|
252
248
|
end
|
253
249
|
end
|
254
|
-
|
data/lib/search_flip/response.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
module SearchFlip
|
3
2
|
# The SearchFlip::Response class wraps a raw SearchFlip response and
|
4
3
|
# decorates it with methods for aggregations, hits, records, pagination, etc.
|
@@ -34,16 +33,16 @@ module SearchFlip
|
|
34
33
|
# Returns the total number of results.
|
35
34
|
#
|
36
35
|
# @example
|
37
|
-
# CommentIndex.search("hello world").
|
36
|
+
# CommentIndex.search("hello world").total_count
|
38
37
|
# # => 13
|
39
38
|
#
|
40
39
|
# @return [Fixnum] The total number of results
|
41
40
|
|
42
|
-
def
|
41
|
+
def total_count
|
43
42
|
hits["total"].is_a?(Hash) ? hits["total"]["value"] : hits["total"]
|
44
43
|
end
|
45
44
|
|
46
|
-
alias_method :
|
45
|
+
alias_method :total_entries, :total_count
|
47
46
|
|
48
47
|
# Returns whether or not the current page is the first page.
|
49
48
|
#
|
@@ -103,7 +102,7 @@ module SearchFlip
|
|
103
102
|
# @return [Fixnum] The current page number
|
104
103
|
|
105
104
|
def current_page
|
106
|
-
1 + (criteria.offset_value_with_default / criteria.limit_value_with_default
|
105
|
+
1 + (criteria.offset_value_with_default / criteria.limit_value_with_default)
|
107
106
|
end
|
108
107
|
|
109
108
|
# Returns the number of total pages for the current pagination settings, ie
|
@@ -116,7 +115,7 @@ module SearchFlip
|
|
116
115
|
# @return [Fixnum] The total number of pages
|
117
116
|
|
118
117
|
def total_pages
|
119
|
-
[(
|
118
|
+
[(total_count.to_f / criteria.limit_value_with_default).ceil, 1].max
|
120
119
|
end
|
121
120
|
|
122
121
|
# Returns the previous page number or nil if no previous page exists, ie if
|
@@ -324,4 +323,3 @@ module SearchFlip
|
|
324
323
|
end
|
325
324
|
end
|
326
325
|
end
|
327
|
-
|
data/lib/search_flip/result.rb
CHANGED
data/lib/search_flip/to_json.rb
CHANGED
@@ -1,31 +1,29 @@
|
|
1
|
-
|
2
1
|
require "time"
|
3
2
|
require "date"
|
4
3
|
require "json"
|
5
4
|
|
6
5
|
class Time
|
7
|
-
def to_json
|
6
|
+
def to_json(*args)
|
8
7
|
iso8601(6).to_json
|
9
8
|
end
|
10
9
|
end
|
11
10
|
|
12
11
|
class Date
|
13
|
-
def to_json
|
12
|
+
def to_json(*args)
|
14
13
|
iso8601.to_json
|
15
14
|
end
|
16
15
|
end
|
17
16
|
|
18
17
|
class DateTime
|
19
|
-
def to_json
|
18
|
+
def to_json(*args)
|
20
19
|
iso8601(6).to_json
|
21
20
|
end
|
22
21
|
end
|
23
22
|
|
24
23
|
if defined?(ActiveSupport)
|
25
24
|
class ActiveSupport::TimeWithZone
|
26
|
-
def to_json
|
25
|
+
def to_json(*args)
|
27
26
|
iso8601(6).to_json
|
28
27
|
end
|
29
28
|
end
|
30
29
|
end
|
31
|
-
|
data/lib/search_flip/version.rb
CHANGED
data/lib/search_flip.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
|
2
|
-
require "ruby2_keywords"
|
3
1
|
require "forwardable"
|
4
2
|
require "http"
|
5
3
|
require "hashie"
|
@@ -8,6 +6,7 @@ require "oj"
|
|
8
6
|
require "set"
|
9
7
|
|
10
8
|
require "search_flip/version"
|
9
|
+
require "search_flip/helper"
|
11
10
|
require "search_flip/exceptions"
|
12
11
|
require "search_flip/json"
|
13
12
|
require "search_flip/http_client"
|
@@ -41,4 +40,3 @@ module SearchFlip
|
|
41
40
|
end
|
42
41
|
end
|
43
42
|
end
|
44
|
-
|
data/search_flip.gemspec
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
lib = File.expand_path("lib", __dir__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
3
|
|
@@ -9,12 +8,12 @@ Gem::Specification.new do |spec|
|
|
9
8
|
spec.version = SearchFlip::VERSION
|
10
9
|
spec.authors = ["Benjamin Vetter"]
|
11
10
|
spec.email = ["vetter@flakks.com"]
|
12
|
-
spec.description =
|
13
|
-
spec.summary =
|
11
|
+
spec.description = "Full-Featured Elasticsearch Ruby Client with a Chainable DSL"
|
12
|
+
spec.summary = "Full-Featured Elasticsearch Ruby Client with a Chainable DSL"
|
14
13
|
spec.homepage = "https://github.com/mrkamel/search_flip"
|
15
14
|
spec.license = "MIT"
|
16
15
|
|
17
|
-
spec.files = `git ls-files`.split(
|
16
|
+
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
18
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
19
|
spec.require_paths = ["lib"]
|
@@ -30,11 +29,11 @@ Gem::Specification.new do |spec|
|
|
30
29
|
spec.add_development_dependency "factory_bot"
|
31
30
|
spec.add_development_dependency "rake"
|
32
31
|
spec.add_development_dependency "rspec"
|
32
|
+
spec.add_development_dependency "rubocop"
|
33
33
|
spec.add_development_dependency "sqlite3"
|
34
34
|
spec.add_development_dependency "timecop"
|
35
35
|
spec.add_development_dependency "webmock"
|
36
36
|
|
37
|
-
spec.add_dependency "ruby2_keywords"
|
38
37
|
spec.add_dependency "hashie"
|
39
38
|
spec.add_dependency "http"
|
40
39
|
spec.add_dependency "oj"
|
data/spec/delegate_matcher.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
require File.expand_path("../spec_helper", __dir__)
|
3
2
|
|
4
3
|
RSpec.describe SearchFlip::Aggregation do
|
@@ -287,8 +286,8 @@ RSpec.describe SearchFlip::Aggregation do
|
|
287
286
|
unsupported_methods = [
|
288
287
|
:profile_value, :failsafe_value, :terminate_after_value, :timeout_value, :offset_value, :limit_value,
|
289
288
|
:scroll_args, :highlight_values, :suggest_values, :custom_value, :source_value, :sort_values,
|
290
|
-
:includes_values, :preload_values, :eager_load_values, :
|
291
|
-
:post_must_not_values, :
|
289
|
+
:includes_values, :preload_values, :eager_load_values, :post_must_values,
|
290
|
+
:post_must_not_values, :post_filter_values, :preference_value,
|
292
291
|
:search_type_value, :routing_value
|
293
292
|
]
|
294
293
|
|
@@ -309,7 +308,7 @@ RSpec.describe SearchFlip::Aggregation do
|
|
309
308
|
end
|
310
309
|
|
311
310
|
describe "array concatenations" do
|
312
|
-
methods = [:
|
311
|
+
methods = [:must_values, :must_not_values, :filter_values]
|
313
312
|
|
314
313
|
methods.each do |method|
|
315
314
|
it "concatenates the values for #{method}" do
|
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
require File.expand_path("../spec_helper", __dir__)
|
3
2
|
|
4
3
|
RSpec.describe SearchFlip::Bulk do
|
@@ -75,34 +74,40 @@ RSpec.describe SearchFlip::Bulk do
|
|
75
74
|
expect(&block).to raise_error(SearchFlip::ResponseError)
|
76
75
|
end
|
77
76
|
|
78
|
-
it "
|
77
|
+
it "transmits up to bulk_max_mb only" do
|
79
78
|
product = create(:product)
|
80
79
|
|
81
|
-
allow(product).to receive(:description).and_return("x" * 1024 * 1024
|
80
|
+
allow(product).to receive(:description).and_return("x" * 1024 * 1024)
|
82
81
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
82
|
+
ProductIndex.bulk bulk_max_mb: 10 do |bulk|
|
83
|
+
allow(bulk).to receive(:upload).and_call_original
|
84
|
+
|
85
|
+
20.times do
|
86
|
+
bulk.index product.id, ProductIndex.serialize(product)
|
88
87
|
end
|
89
|
-
end
|
90
88
|
|
91
|
-
|
92
|
-
expect(&block).to raise_error(SearchFlip::ConnectionError)
|
93
|
-
else
|
94
|
-
expect(&block).to raise_error(SearchFlip::ResponseError)
|
89
|
+
expect(bulk).to have_received(:upload).exactly(2).times
|
95
90
|
end
|
91
|
+
end
|
96
92
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
93
|
+
it "uploads a last time if there is data left within the output buffer" do
|
94
|
+
product = create(:product)
|
95
|
+
|
96
|
+
allow(product).to receive(:description).and_return("x" * 1024 * 1024)
|
97
|
+
|
98
|
+
bulk_upload = nil
|
99
|
+
|
100
|
+
ProductIndex.bulk bulk_max_mb: 5.5 do |bulk|
|
101
|
+
bulk_upload = bulk
|
102
|
+
|
103
|
+
allow(bulk).to receive(:upload).and_call_original
|
104
|
+
|
105
|
+
6.times do
|
106
|
+
bulk.index product.id, ProductIndex.serialize(product)
|
102
107
|
end
|
103
108
|
end
|
104
109
|
|
105
|
-
expect(
|
110
|
+
expect(bulk_upload).to have_received(:upload).exactly(2).times
|
106
111
|
end
|
107
112
|
end
|
108
113
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
require File.expand_path("../spec_helper", __dir__)
|
3
2
|
|
4
3
|
RSpec.describe SearchFlip::Connection do
|
@@ -96,6 +95,12 @@ RSpec.describe SearchFlip::Connection do
|
|
96
95
|
expect(connection.get_indices.map { |index| index["index"] }.to_set).to eq(["comments", "products"].to_set)
|
97
96
|
expect(connection.get_indices("com*").map { |index| index["index"] }).to eq(["comments"])
|
98
97
|
end
|
98
|
+
|
99
|
+
it "accepts additional parameters" do
|
100
|
+
connection = SearchFlip::Connection.new
|
101
|
+
|
102
|
+
expect(connection.get_indices("comments", params: { h: "i" })).to eq([{ "i" => "comments" }])
|
103
|
+
end
|
99
104
|
end
|
100
105
|
|
101
106
|
describe "#create_index" do
|
@@ -114,13 +119,15 @@ RSpec.describe SearchFlip::Connection do
|
|
114
119
|
end
|
115
120
|
|
116
121
|
it "respects a payload" do
|
117
|
-
|
122
|
+
begin
|
123
|
+
connection = SearchFlip::Connection.new
|
118
124
|
|
119
|
-
|
125
|
+
connection.create_index("index_name", settings: { number_of_shards: 3 })
|
120
126
|
|
121
|
-
|
122
|
-
|
123
|
-
|
127
|
+
expect(connection.get_index_settings("index_name")["index_name"]["settings"]["index"]["number_of_shards"]).to eq("3")
|
128
|
+
ensure
|
129
|
+
connection.delete_index("index_name") if connection.index_exists?("index_name")
|
130
|
+
end
|
124
131
|
end
|
125
132
|
end
|
126
133
|
|
@@ -159,6 +166,41 @@ RSpec.describe SearchFlip::Connection do
|
|
159
166
|
end
|
160
167
|
end
|
161
168
|
|
169
|
+
describe "#freeze_index" do
|
170
|
+
it "freezes the specified index" do
|
171
|
+
connection = SearchFlip::Connection.new
|
172
|
+
|
173
|
+
if connection.version.to_f >= 6.6
|
174
|
+
begin
|
175
|
+
connection.create_index("index_name")
|
176
|
+
connection.freeze_index("index_name")
|
177
|
+
|
178
|
+
expect(connection.get_indices("index_name", params: { h: "sth" }).first["sth"]).to eq("true")
|
179
|
+
ensure
|
180
|
+
connection.delete_index("index_name") if connection.index_exists?("index_name")
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe "#unfreeze_index" do
|
187
|
+
it "unfreezes the specified index" do
|
188
|
+
connection = SearchFlip::Connection.new
|
189
|
+
|
190
|
+
if connection.version.to_f >= 6.6
|
191
|
+
begin
|
192
|
+
connection.create_index("index_name")
|
193
|
+
connection.freeze_index("index_name")
|
194
|
+
connection.unfreeze_index("index_name")
|
195
|
+
|
196
|
+
expect(connection.get_indices("index_name", params: { h: "sth" }).first["sth"]).to eq("false")
|
197
|
+
ensure
|
198
|
+
connection.delete_index("index_name") if connection.index_exists?("index_name")
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
162
204
|
describe ".analyze" do
|
163
205
|
it "analyzes the provided request" do
|
164
206
|
connection = SearchFlip::Connection.new
|
@@ -282,4 +324,3 @@ RSpec.describe SearchFlip::Connection do
|
|
282
324
|
end
|
283
325
|
end
|
284
326
|
end
|
285
|
-
|