search_flip 1.1.0 → 2.0.0.beta
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.rubocop.yml +110 -0
- data/.travis.yml +11 -30
- data/CHANGELOG.md +17 -5
- data/README.md +32 -0
- data/docker-compose.yml +6 -0
- data/lib/search_flip.rb +2 -42
- data/lib/search_flip/aggregatable.rb +1 -1
- data/lib/search_flip/aggregation.rb +15 -9
- data/lib/search_flip/bulk.rb +8 -5
- data/lib/search_flip/config.rb +0 -11
- data/lib/search_flip/connection.rb +131 -0
- data/lib/search_flip/criteria.rb +89 -73
- data/lib/search_flip/exceptions.rb +5 -0
- data/lib/search_flip/filterable.rb +3 -1
- data/lib/search_flip/index.rb +32 -26
- data/lib/search_flip/model.rb +1 -1
- data/lib/search_flip/post_filterable.rb +5 -3
- data/lib/search_flip/response.rb +1 -1
- data/lib/search_flip/version.rb +1 -1
- data/search_flip.gemspec +10 -9
- data/test/search_flip/aggregation_test.rb +39 -21
- data/test/search_flip/bulk_test.rb +1 -1
- data/test/search_flip/connection_test.rb +70 -0
- data/test/search_flip/criteria_test.rb +87 -44
- data/test/search_flip/http_client_test.rb +1 -1
- data/test/search_flip/index_test.rb +49 -17
- data/test/search_flip/model_test.rb +1 -1
- data/test/search_flip/response_test.rb +4 -3
- data/test/search_flip/to_json_test.rb +1 -1
- data/test/test_helper.rb +5 -5
- metadata +28 -26
- data/test/database.yml +0 -4
- data/test/search_flip_test.rb +0 -26
data/lib/search_flip/model.rb
CHANGED
@@ -8,7 +8,7 @@ module SearchFlip
|
|
8
8
|
module ClassMethods
|
9
9
|
def notifies_index(index)
|
10
10
|
if respond_to?(:after_commit)
|
11
|
-
after_commit { |record| record.destroyed? ? index.delete(record) : index.import(record)}
|
11
|
+
after_commit { |record| record.destroyed? ? index.delete(record) : index.import(record) }
|
12
12
|
else
|
13
13
|
after_save { |record| index.import(record) }
|
14
14
|
after_touch { |record| index.import(record) } if respond_to?(:after_touch)
|
@@ -42,10 +42,12 @@ module SearchFlip
|
|
42
42
|
# @return [SearchFlip::Criteria] A newly created extended criteria
|
43
43
|
|
44
44
|
def post_search(q, options = {})
|
45
|
-
raise(SearchFlip::NotSupportedError) if
|
45
|
+
raise(SearchFlip::NotSupportedError) if target.connection.version.to_i < 2
|
46
46
|
|
47
47
|
fresh.tap do |criteria|
|
48
|
-
|
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
|
49
51
|
end
|
50
52
|
end
|
51
53
|
|
@@ -105,7 +107,7 @@ module SearchFlip
|
|
105
107
|
# @return [SearchFlip::Criteria] A newly created extended criteria
|
106
108
|
|
107
109
|
def post_where_not(hash)
|
108
|
-
hash.inject(fresh) do |memo, (key,value)|
|
110
|
+
hash.inject(fresh) do |memo, (key, value)|
|
109
111
|
if value.is_a?(Array)
|
110
112
|
memo.post_must_not terms: { key => value }
|
111
113
|
elsif value.is_a?(Range)
|
data/lib/search_flip/response.rb
CHANGED
data/lib/search_flip/version.rb
CHANGED
data/search_flip.gemspec
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path(
|
1
|
+
|
2
|
+
lib = File.expand_path("lib", __dir__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
|
4
|
+
|
5
|
+
require "search_flip/version"
|
5
6
|
|
6
7
|
Gem::Specification.new do |spec|
|
7
8
|
spec.name = "search_flip"
|
@@ -18,17 +19,17 @@ Gem::Specification.new do |spec|
|
|
18
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
20
|
spec.require_paths = ["lib"]
|
20
21
|
|
22
|
+
spec.add_development_dependency "activerecord", ">= 3.0"
|
21
23
|
spec.add_development_dependency "bundler"
|
22
|
-
spec.add_development_dependency "
|
24
|
+
spec.add_development_dependency "factory_bot"
|
23
25
|
spec.add_development_dependency "minitest"
|
24
26
|
spec.add_development_dependency "mocha"
|
25
|
-
spec.add_development_dependency "
|
26
|
-
spec.add_development_dependency "sqlite3"
|
27
|
-
spec.add_development_dependency "activerecord", ">= 3.0"
|
28
|
-
spec.add_development_dependency "webmock"
|
27
|
+
spec.add_development_dependency "rake"
|
28
|
+
spec.add_development_dependency "sqlite3", "~> 1.3.6"
|
29
29
|
spec.add_development_dependency "timecop"
|
30
|
+
spec.add_development_dependency "webmock"
|
30
31
|
|
31
|
-
spec.add_dependency "http"
|
32
32
|
spec.add_dependency "hashie"
|
33
|
+
spec.add_dependency "http"
|
33
34
|
spec.add_dependency "oj"
|
34
35
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
|
2
|
-
require File.expand_path("
|
2
|
+
require File.expand_path("../test_helper", __dir__)
|
3
3
|
|
4
4
|
class SearchFlip::AggregationTest < SearchFlip::TestCase
|
5
5
|
def test_where
|
@@ -15,7 +15,8 @@ class SearchFlip::AggregationTest < SearchFlip::TestCase
|
|
15
15
|
aggregation.where(title: "title").where(description: "description").aggregate(:category)
|
16
16
|
end
|
17
17
|
|
18
|
-
assert_equal Hash["category1" => 2, "category2" => 1],
|
18
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
19
|
+
query.aggregations(:category).category.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
|
19
20
|
end
|
20
21
|
|
21
22
|
def test_where_with_array
|
@@ -28,10 +29,14 @@ class SearchFlip::AggregationTest < SearchFlip::TestCase
|
|
28
29
|
ProductIndex.import [product1, product2, product3, product4, product5]
|
29
30
|
|
30
31
|
query = ProductIndex.aggregate(category: {}) do |aggregation|
|
31
|
-
aggregation
|
32
|
+
aggregation
|
33
|
+
.where(title: ["title1", "title2", "title3", "title4"])
|
34
|
+
.where(description: ["description1", "description2", "description3"])
|
35
|
+
.aggregate(:category)
|
32
36
|
end
|
33
37
|
|
34
|
-
assert_equal Hash["category1" => 2, "category2" => 1],
|
38
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
39
|
+
query.aggregations(:category).category.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
|
35
40
|
end
|
36
41
|
|
37
42
|
def test_where_with_range
|
@@ -44,10 +49,11 @@ class SearchFlip::AggregationTest < SearchFlip::TestCase
|
|
44
49
|
ProductIndex.import [product1, product2, product3, product4, product5]
|
45
50
|
|
46
51
|
query = ProductIndex.aggregate(category: {}) do |aggregation|
|
47
|
-
aggregation.where(title: "title1"
|
52
|
+
aggregation.where(title: "title1".."title3").where(price: 100..200).aggregate(:category)
|
48
53
|
end
|
49
54
|
|
50
|
-
assert_equal Hash["category1" => 2, "category2" => 1],
|
55
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
56
|
+
query.aggregations(:category).category.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
|
51
57
|
end
|
52
58
|
|
53
59
|
def test_where_not
|
@@ -63,7 +69,8 @@ class SearchFlip::AggregationTest < SearchFlip::TestCase
|
|
63
69
|
aggregation.where_not(title: "title4").where_not(title: "title5").aggregate(:category)
|
64
70
|
end
|
65
71
|
|
66
|
-
assert_equal Hash["category1" => 2, "category2" => 1],
|
72
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
73
|
+
query.aggregations(:category).category.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
|
67
74
|
end
|
68
75
|
|
69
76
|
def test_where_not_with_array
|
@@ -81,7 +88,8 @@ class SearchFlip::AggregationTest < SearchFlip::TestCase
|
|
81
88
|
aggregation.where_not(title: ["title1", "title2"]).where_not(title: ["title6", "title7"]).aggregate(:category)
|
82
89
|
end
|
83
90
|
|
84
|
-
assert_equal Hash["category1" => 2, "category2" => 1],
|
91
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
92
|
+
query.aggregations(:category).category.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
|
85
93
|
end
|
86
94
|
|
87
95
|
def test_where_not_with_range
|
@@ -96,10 +104,11 @@ class SearchFlip::AggregationTest < SearchFlip::TestCase
|
|
96
104
|
ProductIndex.import [product1, product2, product3, product4, product5, product6, product7]
|
97
105
|
|
98
106
|
query = ProductIndex.aggregate(category: {}) do |aggregation|
|
99
|
-
aggregation.where_not(price: 100
|
107
|
+
aggregation.where_not(price: 100..150).where_not(title: "title6".."title7").aggregate(:category)
|
100
108
|
end
|
101
109
|
|
102
|
-
assert_equal Hash["category1" => 2, "category2" => 1],
|
110
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
111
|
+
query.aggregations(:category).category.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
|
103
112
|
end
|
104
113
|
|
105
114
|
def test_filter
|
@@ -112,10 +121,11 @@ class SearchFlip::AggregationTest < SearchFlip::TestCase
|
|
112
121
|
ProductIndex.import [product1, product2, product3, product4, product5]
|
113
122
|
|
114
123
|
query = ProductIndex.aggregate(category: {}) do |aggregation|
|
115
|
-
aggregation.filter(range: { price: { gte: 100, lte: 200 }}).filter(term: { title: "title" }).aggregate(:category)
|
124
|
+
aggregation.filter(range: { price: { gte: 100, lte: 200 } }).filter(term: { title: "title" }).aggregate(:category)
|
116
125
|
end
|
117
126
|
|
118
|
-
assert_equal Hash["category1" => 2, "category2" => 1],
|
127
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
128
|
+
query.aggregations(:category).category.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
|
119
129
|
end
|
120
130
|
|
121
131
|
def test_range
|
@@ -133,7 +143,8 @@ class SearchFlip::AggregationTest < SearchFlip::TestCase
|
|
133
143
|
aggregation.range(:price, gte: 100, lte: 200).range(:title, gte: "title1", lte: "title3").aggregate(:category)
|
134
144
|
end
|
135
145
|
|
136
|
-
assert_equal Hash["category1" => 2, "category2" => 1],
|
146
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
147
|
+
query.aggregations(:category).category.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
|
137
148
|
end
|
138
149
|
|
139
150
|
def test_match_all
|
@@ -147,7 +158,8 @@ class SearchFlip::AggregationTest < SearchFlip::TestCase
|
|
147
158
|
aggregation.match_all.aggregate(:category)
|
148
159
|
end
|
149
160
|
|
150
|
-
assert_equal Hash["category1" => 2, "category2" => 1],
|
161
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
162
|
+
query.aggregations(:category).category.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
|
151
163
|
end
|
152
164
|
|
153
165
|
def test_exists
|
@@ -163,7 +175,8 @@ class SearchFlip::AggregationTest < SearchFlip::TestCase
|
|
163
175
|
aggregation.exists(:title).exists(:price).aggregate(:category)
|
164
176
|
end
|
165
177
|
|
166
|
-
assert_equal Hash["category1" => 2, "category2" => 1],
|
178
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
179
|
+
query.aggregations(:category).category.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
|
167
180
|
end
|
168
181
|
|
169
182
|
def test_exists_not
|
@@ -179,7 +192,8 @@ class SearchFlip::AggregationTest < SearchFlip::TestCase
|
|
179
192
|
aggregation.exists_not(:title).exists_not(:price).aggregate(:category)
|
180
193
|
end
|
181
194
|
|
182
|
-
assert_equal Hash["category1" => 2, "category2" => 1],
|
195
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
196
|
+
query.aggregations(:category).category.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
|
183
197
|
end
|
184
198
|
|
185
199
|
def test_aggregate
|
@@ -193,15 +207,19 @@ class SearchFlip::AggregationTest < SearchFlip::TestCase
|
|
193
207
|
ProductIndex.import [product1, product2, product3, product4, product5, product6]
|
194
208
|
|
195
209
|
query = ProductIndex.aggregate(:category) do |aggregation|
|
196
|
-
aggregation.aggregate(:title) do |
|
197
|
-
|
210
|
+
aggregation.aggregate(:title) do |aggregation2|
|
211
|
+
aggregation2.aggregate(price: { sum: { field: "price" } })
|
198
212
|
end
|
199
213
|
end
|
200
214
|
|
201
|
-
assert_equal Hash["category1" => 3, "category2" => 3],
|
215
|
+
assert_equal Hash["category1" => 3, "category2" => 3],
|
216
|
+
query.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
|
202
217
|
|
203
|
-
assert_equal Hash["title1" => 2, "title2" => 1],
|
204
|
-
|
218
|
+
assert_equal Hash["title1" => 2, "title2" => 1],
|
219
|
+
query.aggregations(:category)["category1"].title.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
|
220
|
+
|
221
|
+
assert_equal Hash["title1" => 1, "title2" => 2],
|
222
|
+
query.aggregations(:category)["category2"].title.buckets.each_with_object({}) { |bucket, hash| hash[bucket[:key]] = bucket.doc_count }
|
205
223
|
|
206
224
|
assert_equal 30, query.aggregations(:category)["category1"].title.buckets.detect { |bucket| bucket[:key] == "title1" }.price.value
|
207
225
|
assert_equal 15, query.aggregations(:category)["category1"].title.buckets.detect { |bucket| bucket[:key] == "title2" }.price.value
|
@@ -0,0 +1,70 @@
|
|
1
|
+
|
2
|
+
require File.expand_path("../test_helper", __dir__)
|
3
|
+
|
4
|
+
class SearchFlip::ConnectionTest < SearchFlip::TestCase
|
5
|
+
def test_base_url
|
6
|
+
assert_equal SearchFlip::Connection.new(base_url: "base url").base_url, "base url"
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_msearch
|
10
|
+
ProductIndex.import create(:product)
|
11
|
+
CommentIndex.import create(:comment)
|
12
|
+
|
13
|
+
responses = SearchFlip::Connection.new.msearch([ProductIndex.match_all, CommentIndex.match_all])
|
14
|
+
|
15
|
+
assert_equal 2, responses.size
|
16
|
+
assert_equal 1, responses[0].total_entries
|
17
|
+
assert_equal 1, responses[1].total_entries
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_update_aliases
|
21
|
+
connection = SearchFlip::Connection.new
|
22
|
+
|
23
|
+
assert connection.update_aliases(actions: [add: { index: "products", alias: "alias1" }])
|
24
|
+
assert connection.update_aliases(actions: [remove: { index: "products", alias: "alias1" }])
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_get_index_aliases
|
28
|
+
connection = SearchFlip::Connection.new
|
29
|
+
|
30
|
+
connection.update_aliases(actions: [
|
31
|
+
{ add: { index: "comments", alias: "alias1" } },
|
32
|
+
{ add: { index: "products", alias: "alias2" } },
|
33
|
+
{ add: { index: "products", alias: "alias3" } }
|
34
|
+
])
|
35
|
+
|
36
|
+
assert_equal connection.get_aliases.keys.sort, ["comments", "products"].sort
|
37
|
+
assert_equal connection.get_aliases["products"]["aliases"].keys, ["alias2", "alias3"]
|
38
|
+
assert_equal connection.get_aliases["comments"]["aliases"].keys, ["alias1"]
|
39
|
+
assert_equal connection.get_aliases(index_name: "products").keys, ["products"]
|
40
|
+
assert_equal connection.get_aliases(index_name: "comments,products").keys.sort, ["comments", "products"]
|
41
|
+
assert_equal connection.get_aliases(alias_name: "alias1,alias2").keys.sort, ["comments", "products"]
|
42
|
+
assert_equal connection.get_aliases(alias_name: "alias1,alias2")["products"]["aliases"].keys, ["alias2"]
|
43
|
+
ensure
|
44
|
+
connection.update_aliases(actions: [
|
45
|
+
{ remove: { index: "comments", alias: "alias1" } },
|
46
|
+
{ remove: { index: "products", alias: "alias2" } },
|
47
|
+
{ remove: { index: "products", alias: "alias3" } }
|
48
|
+
])
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_alias_exists?
|
52
|
+
connection = SearchFlip::Connection.new
|
53
|
+
|
54
|
+
refute connection.alias_exists?(:some_alias)
|
55
|
+
|
56
|
+
connection.update_aliases(actions: [add: { index: "products", alias: "some_alias" }])
|
57
|
+
|
58
|
+
assert connection.alias_exists?(:some_alias)
|
59
|
+
ensure
|
60
|
+
connection.update_aliases(actions: [remove: { index: "products", alias: "some_alias" }])
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_get_indices
|
64
|
+
connection = SearchFlip::Connection.new
|
65
|
+
|
66
|
+
assert_equal connection.get_indices.map { |index| index["index"] }.sort, ["comments", "products"]
|
67
|
+
assert_equal connection.get_indices("com*").map { |index| index["index"] }.sort, ["comments"]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
@@ -1,9 +1,10 @@
|
|
1
1
|
|
2
|
-
require File.expand_path("
|
2
|
+
require File.expand_path("../test_helper", __dir__)
|
3
3
|
|
4
4
|
class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
5
|
-
should_delegate_methods :total_entries, :current_page, :previous_page, :prev_page, :next_page,
|
6
|
-
:total_pages, :hits, :ids, :count, :size, :length,
|
5
|
+
should_delegate_methods :total_entries, :current_page, :previous_page, :prev_page, :next_page,
|
6
|
+
:first_page?, :last_page?, :out_of_range?, :total_pages, :hits, :ids, :count, :size, :length,
|
7
|
+
:took, :aggregations, :suggestions, :scope, :results, :records, :scroll_id, :raw_response,
|
7
8
|
to: :response, subject: SearchFlip::Criteria.new(target: ProductIndex)
|
8
9
|
|
9
10
|
def test_merge
|
@@ -13,7 +14,7 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
13
14
|
|
14
15
|
ProductIndex.import [product1, product2, product3]
|
15
16
|
|
16
|
-
query = ProductIndex.where(price: 50
|
17
|
+
query = ProductIndex.where(price: 50..250).aggregate(:category).merge(ProductIndex.where(category: "category1"))
|
17
18
|
|
18
19
|
assert_includes query.records, product1
|
19
20
|
refute_includes query.records, product2
|
@@ -23,7 +24,7 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
23
24
|
def test_criteria
|
24
25
|
criteria = ProductIndex.criteria
|
25
26
|
|
26
|
-
|
27
|
+
assert_equal criteria.criteria.object_id, criteria.object_id
|
27
28
|
end
|
28
29
|
|
29
30
|
def test_timeout
|
@@ -49,7 +50,7 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
49
50
|
|
50
51
|
ProductIndex.import [product1, product2, product3]
|
51
52
|
|
52
|
-
query1 = ProductIndex.where(price: 100
|
53
|
+
query1 = ProductIndex.where(price: 100..200)
|
53
54
|
query2 = query1.where(category: "category1")
|
54
55
|
|
55
56
|
assert_includes query1.records, product1
|
@@ -82,7 +83,7 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
82
83
|
|
83
84
|
ProductIndex.import [expected1, expected2, rejected]
|
84
85
|
|
85
|
-
records = ProductIndex.where(price: 100
|
86
|
+
records = ProductIndex.where(price: 100..200).records
|
86
87
|
|
87
88
|
assert_includes records, expected1
|
88
89
|
assert_includes records, expected2
|
@@ -108,7 +109,7 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
108
109
|
|
109
110
|
ProductIndex.import [product1, product2, product3]
|
110
111
|
|
111
|
-
query1 = ProductIndex.where_not(price: 250
|
112
|
+
query1 = ProductIndex.where_not(price: 250..350)
|
112
113
|
query2 = query1.where_not(category: "category2")
|
113
114
|
|
114
115
|
assert_includes query1.records, product1
|
@@ -141,7 +142,7 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
141
142
|
|
142
143
|
ProductIndex.import [expected, rejected1, rejected2]
|
143
144
|
|
144
|
-
records = ProductIndex.where_not(price: 200
|
145
|
+
records = ProductIndex.where_not(price: 200..300).records
|
145
146
|
|
146
147
|
assert_includes records, expected
|
147
148
|
refute_includes records, rejected1
|
@@ -167,7 +168,7 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
167
168
|
|
168
169
|
ProductIndex.import [product1, product2, product3]
|
169
170
|
|
170
|
-
query1 = ProductIndex.filter(range: { price: { gte: 100, lte: 200 }})
|
171
|
+
query1 = ProductIndex.filter(range: { price: { gte: 100, lte: 200 } })
|
171
172
|
query2 = query1.filter(term: { category: "category1" })
|
172
173
|
|
173
174
|
assert_includes query1.records, product1
|
@@ -210,6 +211,15 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
210
211
|
assert_includes records, expected2
|
211
212
|
end
|
212
213
|
|
214
|
+
def test_execute
|
215
|
+
connection = SearchFlip::Connection.new(base_url: "http://localhost:1234")
|
216
|
+
|
217
|
+
stub_request(:post, "http://localhost:1234/products/products/_search")
|
218
|
+
.to_return(status: 200, body: "{}", headers: { content_type: "application/json" })
|
219
|
+
|
220
|
+
assert_equal ProductIndex.match_all.execute(connection: connection).raw_response, {}
|
221
|
+
end
|
222
|
+
|
213
223
|
def test_exists
|
214
224
|
product1 = create(:product, title: "title1", description: "description1")
|
215
225
|
product2 = create(:product, title: "title2", description: nil)
|
@@ -249,7 +259,7 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
249
259
|
end
|
250
260
|
|
251
261
|
def test_post_search
|
252
|
-
return if
|
262
|
+
return if ProductIndex.connection.version.to_i < 2
|
253
263
|
|
254
264
|
product1 = create(:product, title: "title1", category: "category1")
|
255
265
|
product2 = create(:product, title: "title2", category: "category2")
|
@@ -268,8 +278,11 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
268
278
|
refute_includes query2.records, product2
|
269
279
|
refute_includes query2.records, product3
|
270
280
|
|
271
|
-
assert_equal Hash["category1" => 2, "category2" => 1],
|
272
|
-
|
281
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
282
|
+
query1.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
|
283
|
+
|
284
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
285
|
+
query2.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
|
273
286
|
end
|
274
287
|
|
275
288
|
def test_post_where
|
@@ -279,7 +292,7 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
279
292
|
|
280
293
|
ProductIndex.import [product1, product2, product3]
|
281
294
|
|
282
|
-
query1 = ProductIndex.aggregate(:category).post_where(price: 100
|
295
|
+
query1 = ProductIndex.aggregate(:category).post_where(price: 100..200)
|
283
296
|
query2 = query1.post_where(category: "category1")
|
284
297
|
|
285
298
|
assert_includes query1.records, product1
|
@@ -290,8 +303,11 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
290
303
|
refute_includes query2.records, product2
|
291
304
|
refute_includes query2.records, product3
|
292
305
|
|
293
|
-
assert_equal Hash["category1" => 2, "category2" => 1],
|
294
|
-
|
306
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
307
|
+
query1.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
|
308
|
+
|
309
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
310
|
+
query2.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
|
295
311
|
end
|
296
312
|
|
297
313
|
def test_post_where_with_array
|
@@ -307,7 +323,8 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
307
323
|
assert_includes query.records, expected2
|
308
324
|
refute_includes query.records, rejected
|
309
325
|
|
310
|
-
assert_equal Hash["category1" => 2, "category2" => 1],
|
326
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
327
|
+
query.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
|
311
328
|
end
|
312
329
|
|
313
330
|
def test_post_where_with_range
|
@@ -317,13 +334,14 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
317
334
|
|
318
335
|
ProductIndex.import [expected1, expected2, rejected]
|
319
336
|
|
320
|
-
query = ProductIndex.aggregate(:category).post_where(price: 100
|
337
|
+
query = ProductIndex.aggregate(:category).post_where(price: 100..200)
|
321
338
|
|
322
339
|
assert_includes query.records, expected1
|
323
340
|
assert_includes query.records, expected2
|
324
341
|
refute_includes query.records, rejected
|
325
342
|
|
326
|
-
assert_equal Hash["category1" => 2, "category2" => 1],
|
343
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
344
|
+
query.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
|
327
345
|
end
|
328
346
|
|
329
347
|
def test_post_where_not
|
@@ -333,7 +351,7 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
333
351
|
|
334
352
|
ProductIndex.import [product1, product2, product3]
|
335
353
|
|
336
|
-
query1 = ProductIndex.aggregate(:category).post_where_not(price: 250
|
354
|
+
query1 = ProductIndex.aggregate(:category).post_where_not(price: 250..350)
|
337
355
|
query2 = query1.post_where_not(category: "category2")
|
338
356
|
|
339
357
|
assert_includes query1.records, product1
|
@@ -344,8 +362,11 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
344
362
|
refute_includes query2.records, product2
|
345
363
|
refute_includes query2.records, product3
|
346
364
|
|
347
|
-
assert_equal Hash["category1" => 2, "category2" => 1],
|
348
|
-
|
365
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
366
|
+
query1.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
|
367
|
+
|
368
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
369
|
+
query2.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
|
349
370
|
end
|
350
371
|
|
351
372
|
def test_post_where_not_with_array
|
@@ -361,7 +382,8 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
361
382
|
refute_includes query.records, rejected1
|
362
383
|
refute_includes query.records, rejected2
|
363
384
|
|
364
|
-
assert_equal Hash["category1" => 2, "category2" => 1],
|
385
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
386
|
+
query.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
|
365
387
|
end
|
366
388
|
|
367
389
|
def test_post_where_not_with_range
|
@@ -371,13 +393,14 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
371
393
|
|
372
394
|
ProductIndex.import [expected, rejected1, rejected2]
|
373
395
|
|
374
|
-
query = ProductIndex.aggregate(:category).post_where_not(price: 200
|
396
|
+
query = ProductIndex.aggregate(:category).post_where_not(price: 200..300)
|
375
397
|
|
376
398
|
assert_includes query.records, expected
|
377
399
|
refute_includes query.records, rejected1
|
378
400
|
refute_includes query.records, rejected2
|
379
401
|
|
380
|
-
assert_equal Hash["category1" => 2, "category2" => 1],
|
402
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
403
|
+
query.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
|
381
404
|
end
|
382
405
|
|
383
406
|
def test_post_filter
|
@@ -387,7 +410,7 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
387
410
|
|
388
411
|
ProductIndex.import [product1, product2, product3]
|
389
412
|
|
390
|
-
query1 = ProductIndex.aggregate(:category).post_filter(range: { price: { gte: 100, lte: 200 }})
|
413
|
+
query1 = ProductIndex.aggregate(:category).post_filter(range: { price: { gte: 100, lte: 200 } })
|
391
414
|
query2 = query1.post_filter(term: { category: "category1" })
|
392
415
|
|
393
416
|
assert_includes query1.records, product1
|
@@ -398,8 +421,11 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
398
421
|
refute_includes query2.records, product2
|
399
422
|
refute_includes query2.records, product3
|
400
423
|
|
401
|
-
assert_equal Hash["category1" => 2, "category2" => 1],
|
402
|
-
|
424
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
425
|
+
query1.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
|
426
|
+
|
427
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
428
|
+
query2.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
|
403
429
|
end
|
404
430
|
|
405
431
|
def test_post_range
|
@@ -420,8 +446,11 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
420
446
|
assert_includes query2.records, product2
|
421
447
|
refute_includes query2.records, product3
|
422
448
|
|
423
|
-
assert_equal Hash["category1" => 2, "category2" => 1],
|
424
|
-
|
449
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
450
|
+
query1.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
|
451
|
+
|
452
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
453
|
+
query2.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
|
425
454
|
end
|
426
455
|
|
427
456
|
def test_post_exists
|
@@ -442,8 +471,11 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
442
471
|
refute_includes query2.records, product2
|
443
472
|
refute_includes query2.records, product3
|
444
473
|
|
445
|
-
assert_equal Hash["category1" => 2, "category2" => 1],
|
446
|
-
|
474
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
475
|
+
query1.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
|
476
|
+
|
477
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
478
|
+
query2.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
|
447
479
|
end
|
448
480
|
|
449
481
|
def test_post_exists_not
|
@@ -464,8 +496,11 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
464
496
|
refute_includes query2.records, product2
|
465
497
|
refute_includes query2.records, product3
|
466
498
|
|
467
|
-
assert_equal Hash["category1" => 2, "category2" => 1],
|
468
|
-
|
499
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
500
|
+
query1.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
|
501
|
+
|
502
|
+
assert_equal Hash["category1" => 2, "category2" => 1],
|
503
|
+
query2.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
|
469
504
|
end
|
470
505
|
|
471
506
|
def test_aggregate
|
@@ -473,7 +508,7 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
473
508
|
ProductIndex.import create_list(:product, 2, category: "category2", price: 20)
|
474
509
|
ProductIndex.import create_list(:product, 1, category: "category3", price: 30)
|
475
510
|
|
476
|
-
query = ProductIndex.aggregate(:category, size: 2).aggregate(price_sum: { sum: { field: "price" }})
|
511
|
+
query = ProductIndex.aggregate(:category, size: 2).aggregate(price_sum: { sum: { field: "price" } })
|
477
512
|
|
478
513
|
category_aggregations = query.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
|
479
514
|
price_aggregation = query.aggregations(:price_sum).value
|
@@ -487,7 +522,8 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
487
522
|
ProductIndex.import create_list(:product, 2, category: "category2")
|
488
523
|
ProductIndex.import create_list(:product, 1, category: "category3")
|
489
524
|
|
490
|
-
|
525
|
+
query = ProductIndex.aggregate(category: { terms: { field: :category } })
|
526
|
+
aggregations = query.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
|
491
527
|
|
492
528
|
assert_equal Hash["category1" => 3, "category2" => 2, "category3" => 1], aggregations
|
493
529
|
end
|
@@ -498,7 +534,7 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
498
534
|
ProductIndex.import create_list(:product, 1, category: "category3", price: 25)
|
499
535
|
|
500
536
|
query = ProductIndex.aggregate(:category) do |aggregation|
|
501
|
-
aggregation.aggregate(price_sum: { sum: { field: "price" }})
|
537
|
+
aggregation.aggregate(price_sum: { sum: { field: "price" } })
|
502
538
|
end
|
503
539
|
|
504
540
|
category_aggregations = query.aggregations(:category).each_with_object({}) { |(key, agg), hash| hash[key] = agg.doc_count }
|
@@ -509,7 +545,7 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
509
545
|
end
|
510
546
|
|
511
547
|
def test_profile
|
512
|
-
return if
|
548
|
+
return if ProductIndex.connection.version.to_i < 2
|
513
549
|
|
514
550
|
assert_not_nil ProductIndex.profile(true).raw_response["profile"]
|
515
551
|
end
|
@@ -689,7 +725,7 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
689
725
|
assert_equal [product1, product3].to_set, ProductIndex.search("Title1 OR Title3").records.to_set
|
690
726
|
assert_equal [product1, product3].to_set, ProductIndex.search("Title1 Title3", default_operator: :OR).records.to_set
|
691
727
|
assert_equal [product1], ProductIndex.search("Title1 OR Title2").search("Title1 OR Title3").records
|
692
|
-
assert_equal [product1], ProductIndex.search("Title1 OR Title3").where(price: 5
|
728
|
+
assert_equal [product1], ProductIndex.search("Title1 OR Title3").where(price: 5..15).records
|
693
729
|
end
|
694
730
|
|
695
731
|
def test_unscope
|
@@ -725,7 +761,10 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
725
761
|
assert_equal ["Title2 <em>highlight</em>"], results[1].highlight.title
|
726
762
|
assert_equal ["Description2 <em>highlight</em>"], results[1].highlight.description
|
727
763
|
|
728
|
-
|
764
|
+
query = ProductIndex.sort(:id).search("title:highlight")
|
765
|
+
query = query.highlight(:title, require_field_match: true).highlight(:description, require_field_match: true)
|
766
|
+
|
767
|
+
results = query.results
|
729
768
|
|
730
769
|
assert_equal ["Title1 <em>highlight</em>"], results[0].highlight.title
|
731
770
|
assert_nil results[0].highlight.description
|
@@ -739,7 +778,8 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
739
778
|
|
740
779
|
ProductIndex.import product
|
741
780
|
|
742
|
-
assert_equal "description",
|
781
|
+
assert_equal "description",
|
782
|
+
ProductIndex.suggest(:suggestion, text: "Desciption", term: { field: "description" }).suggestions(:suggestion).first["text"]
|
743
783
|
end
|
744
784
|
|
745
785
|
def test_find_in_batches
|
@@ -752,7 +792,8 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
752
792
|
|
753
793
|
ProductIndex.import [expected1, expected2, expected3, rejected]
|
754
794
|
|
755
|
-
assert_equal [[expected1, expected2], [expected3]],
|
795
|
+
assert_equal [[expected1, expected2], [expected3]],
|
796
|
+
ProductIndex.where(title: "expected").sort(:rank).find_in_batches(batch_size: 2).to_a
|
756
797
|
end
|
757
798
|
|
758
799
|
def test_find_results_in_batches
|
@@ -765,7 +806,9 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
765
806
|
|
766
807
|
ProductIndex.import [expected1, expected2, expected3, rejected]
|
767
808
|
|
768
|
-
|
809
|
+
actual = ProductIndex.where(title: "expected").sort(:rank).find_results_in_batches(batch_size: 2).map { |batch| batch.map(&:id) }
|
810
|
+
|
811
|
+
assert_equal [[expected1.id, expected2.id], [expected3.id]], actual
|
769
812
|
end
|
770
813
|
|
771
814
|
def test_find_each
|
@@ -799,7 +842,7 @@ class SearchFlip::CriteriaTest < SearchFlip::TestCase
|
|
799
842
|
|
800
843
|
assert_not_nil query.instance_variable_get(:@response)
|
801
844
|
|
802
|
-
|
845
|
+
refute_equal query.fresh.object_id, query.object_id
|
803
846
|
assert_nil query.fresh.instance_variable_get(:@response)
|
804
847
|
end
|
805
848
|
|