search_flip 1.1.0 → 2.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 +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
|
|