searchkick 2.2.0 → 2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/CHANGELOG.md +7 -0
- data/README.md +15 -3
- data/Rakefile +7 -0
- data/lib/searchkick.rb +1 -1
- data/lib/searchkick/model.rb +2 -2
- data/lib/searchkick/query.rb +9 -1
- data/lib/searchkick/results.rb +1 -1
- data/lib/searchkick/version.rb +1 -1
- data/test/aggs_test.rb +62 -0
- data/test/gemfiles/parallel_tests.gemfile +8 -0
- data/test/index_test.rb +5 -3
- data/test/marshal_test.rb +8 -0
- data/test/match_test.rb +5 -0
- data/test/sql_test.rb +5 -0
- data/test/test_helper.rb +7 -2
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e592f63efa26867238f106cdede925736897c39e
|
4
|
+
data.tar.gz: b873c66a18f69cffcd9227fe92a1cf314e602090
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 74566048b5471575f1c7f2e269a6fa23fa62dbbd717696a077a26875f43883be128cbbb731578634ec948c51a5e9d336ed3595ea631717ac3056f784c813f19c
|
7
|
+
data.tar.gz: 5c1a40b9633f70201a13e003a1852d5a3cfcf0d16d23024cea19ddce523b2f32e5675119e5899b1b4c3e7f057466cd09a80a788a655933923a78172b5b95ebb0
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## 2.2.1
|
2
|
+
|
3
|
+
- Added `avg`, `cardinality`, `max`, `min`, and `sum` aggregations
|
4
|
+
- Added `load: {dumpable: true}` option
|
5
|
+
- Added `index_suffix` option
|
6
|
+
- Accept string for `exclude` option
|
7
|
+
|
1
8
|
## 2.2.0
|
2
9
|
|
3
10
|
- Fixed bug with text values longer than 256 characters and `_all` field - see [#850](https://github.com/ankane/searchkick/issues/850)
|
data/README.md
CHANGED
@@ -294,13 +294,17 @@ end
|
|
294
294
|
```ruby
|
295
295
|
class Product < ActiveRecord::Base
|
296
296
|
searchkick synonyms: [["scallion", "green onion"], ["qtip", "cotton swab"]]
|
297
|
-
# or
|
298
|
-
# searchkick synonyms: -> { CSV.read("/some/path/synonyms.csv") }
|
299
297
|
end
|
300
298
|
```
|
301
299
|
|
302
300
|
Call `Product.reindex` after changing synonyms.
|
303
301
|
|
302
|
+
To read synonyms from a file, use:
|
303
|
+
|
304
|
+
```ruby
|
305
|
+
synonyms: -> { CSV.read("/some/path/synonyms.csv") }
|
306
|
+
```
|
307
|
+
|
304
308
|
For directional synonyms, use:
|
305
309
|
|
306
310
|
```ruby
|
@@ -388,7 +392,7 @@ You can map queries and terms to exclude with:
|
|
388
392
|
```ruby
|
389
393
|
exclude_queries = {
|
390
394
|
"butter" => ["peanut butter"],
|
391
|
-
"cream" => ["ice cream"]
|
395
|
+
"cream" => ["ice cream", "whipped cream"]
|
392
396
|
}
|
393
397
|
|
394
398
|
Product.search query, exclude: exclude_queries[query]
|
@@ -1766,6 +1770,14 @@ product = FactoryGirl.create(:product)
|
|
1766
1770
|
product.reindex(refresh: true)
|
1767
1771
|
```
|
1768
1772
|
|
1773
|
+
### Parallel Tests
|
1774
|
+
|
1775
|
+
Set:
|
1776
|
+
|
1777
|
+
```ruby
|
1778
|
+
Searchkick.index_suffix = ENV["TEST_ENV_NUMBER"]
|
1779
|
+
```
|
1780
|
+
|
1769
1781
|
## Multi-Tenancy
|
1770
1782
|
|
1771
1783
|
Check out [this great post](https://www.tiagoamaro.com.br/2014/12/11/multi-tenancy-with-searchkick/) on the [Apartment](https://github.com/influitive/apartment) gem. Follow a similar pattern if you use another gem.
|
data/Rakefile
CHANGED
data/lib/searchkick.rb
CHANGED
@@ -36,7 +36,7 @@ module Searchkick
|
|
36
36
|
class ImportError < Error; end
|
37
37
|
|
38
38
|
class << self
|
39
|
-
attr_accessor :search_method_name, :wordnet_path, :timeout, :models, :client_options, :redis
|
39
|
+
attr_accessor :search_method_name, :wordnet_path, :timeout, :models, :client_options, :redis, :index_suffix
|
40
40
|
attr_writer :client, :env, :search_timeout
|
41
41
|
attr_reader :aws_credentials
|
42
42
|
end
|
data/lib/searchkick/model.rb
CHANGED
@@ -21,8 +21,8 @@ module Searchkick
|
|
21
21
|
class_variable_set :@@searchkick_klass, self
|
22
22
|
class_variable_set :@@searchkick_callbacks, callbacks
|
23
23
|
class_variable_set :@@searchkick_index, options[:index_name] ||
|
24
|
-
(options[:index_prefix].respond_to?(:call) && proc { [options[:index_prefix].call, model_name.plural, Searchkick.env].compact.join("_") }) ||
|
25
|
-
[options[:index_prefix], model_name.plural, Searchkick.env].compact.join("_")
|
24
|
+
(options[:index_prefix].respond_to?(:call) && proc { [options[:index_prefix].call, model_name.plural, Searchkick.env, Searchkick.index_suffix].compact.join("_") }) ||
|
25
|
+
[options[:index_prefix], model_name.plural, Searchkick.env, Searchkick.index_suffix].compact.join("_")
|
26
26
|
|
27
27
|
class << self
|
28
28
|
def searchkick_search(term = "*", **options, &block)
|
data/lib/searchkick/query.rb
CHANGED
@@ -2,6 +2,8 @@ module Searchkick
|
|
2
2
|
class Query
|
3
3
|
extend Forwardable
|
4
4
|
|
5
|
+
@@metric_aggs = [:avg, :cardinality, :max, :min, :sum]
|
6
|
+
|
5
7
|
attr_reader :klass, :term, :options
|
6
8
|
attr_accessor :body
|
7
9
|
|
@@ -328,7 +330,7 @@ module Searchkick
|
|
328
330
|
|
329
331
|
if options[:exclude]
|
330
332
|
must_not =
|
331
|
-
options[:exclude].map do |phrase|
|
333
|
+
Array(options[:exclude]).map do |phrase|
|
332
334
|
{
|
333
335
|
match_phrase: {
|
334
336
|
exclude_field => {
|
@@ -643,6 +645,12 @@ module Searchkick
|
|
643
645
|
interval: interval
|
644
646
|
}
|
645
647
|
}
|
648
|
+
elsif metric = @@metric_aggs.find { |k| agg_options.has_key?(k) }
|
649
|
+
payload[:aggs][field] = {
|
650
|
+
metric => {
|
651
|
+
field: agg_options[metric][:field] || field
|
652
|
+
}
|
653
|
+
}
|
646
654
|
else
|
647
655
|
payload[:aggs][field] = {
|
648
656
|
terms: {
|
data/lib/searchkick/results.rb
CHANGED
@@ -33,7 +33,7 @@ module Searchkick
|
|
33
33
|
# sort
|
34
34
|
hits.map do |hit|
|
35
35
|
result = results[hit["_type"]][hit["_id"].to_s]
|
36
|
-
if result
|
36
|
+
if result && !(options[:load].is_a?(Hash) && options[:load][:dumpable])
|
37
37
|
unless result.respond_to?(:search_hit)
|
38
38
|
result.define_singleton_method(:search_hit) do
|
39
39
|
hit
|
data/lib/searchkick/version.rb
CHANGED
data/test/aggs_test.rb
CHANGED
@@ -116,6 +116,68 @@ class AggsTest < Minitest::Test
|
|
116
116
|
assert_equal 4, products.aggs["products_per_year"]["buckets"].size
|
117
117
|
end
|
118
118
|
|
119
|
+
def test_aggs_avg
|
120
|
+
products =
|
121
|
+
Product.search("*", {
|
122
|
+
aggs: {
|
123
|
+
avg_price: {
|
124
|
+
avg: {
|
125
|
+
field: :price
|
126
|
+
}
|
127
|
+
}
|
128
|
+
}
|
129
|
+
})
|
130
|
+
assert_equal 16.5, products.aggs["avg_price"]["value"]
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_aggs_cardinality
|
134
|
+
products =
|
135
|
+
Product.search("*", {
|
136
|
+
aggs: {
|
137
|
+
total_stores: {
|
138
|
+
cardinality: {
|
139
|
+
field: :store_id
|
140
|
+
}
|
141
|
+
}
|
142
|
+
}
|
143
|
+
})
|
144
|
+
assert_equal 3, products.aggs["total_stores"]["value"]
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_aggs_min_max
|
148
|
+
products =
|
149
|
+
Product.search("*", {
|
150
|
+
aggs: {
|
151
|
+
min_price: {
|
152
|
+
min: {
|
153
|
+
field: :price
|
154
|
+
}
|
155
|
+
},
|
156
|
+
max_price: {
|
157
|
+
max: {
|
158
|
+
field: :price
|
159
|
+
}
|
160
|
+
}
|
161
|
+
}
|
162
|
+
})
|
163
|
+
assert_equal 5, products.aggs["min_price"]["value"]
|
164
|
+
assert_equal 25, products.aggs["max_price"]["value"]
|
165
|
+
end
|
166
|
+
|
167
|
+
def test_aggs_sum
|
168
|
+
products =
|
169
|
+
Product.search("*", {
|
170
|
+
aggs: {
|
171
|
+
sum_price: {
|
172
|
+
sum: {
|
173
|
+
field: :price
|
174
|
+
}
|
175
|
+
}
|
176
|
+
}
|
177
|
+
})
|
178
|
+
assert_equal 66, products.aggs["sum_price"]["value"]
|
179
|
+
end
|
180
|
+
|
119
181
|
protected
|
120
182
|
|
121
183
|
def buckets_as_hash(agg)
|
data/test/index_test.rb
CHANGED
@@ -7,8 +7,9 @@ class IndexTest < Minitest::Test
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def test_clean_indices
|
10
|
-
|
11
|
-
|
10
|
+
suffix = Searchkick.index_suffix ? "_#{Searchkick.index_suffix}" : ""
|
11
|
+
old_index = Searchkick::Index.new("products_test#{suffix}_20130801000000000")
|
12
|
+
different_index = Searchkick::Index.new("items_test#{suffix}_20130801000000000")
|
12
13
|
|
13
14
|
old_index.delete if old_index.exists?
|
14
15
|
different_index.delete if different_index.exists?
|
@@ -25,7 +26,8 @@ class IndexTest < Minitest::Test
|
|
25
26
|
end
|
26
27
|
|
27
28
|
def test_clean_indices_old_format
|
28
|
-
|
29
|
+
suffix = Searchkick.index_suffix ? "_#{Searchkick.index_suffix}" : ""
|
30
|
+
old_index = Searchkick::Index.new("products_test#{suffix}_20130801000000")
|
29
31
|
old_index.create
|
30
32
|
|
31
33
|
Product.searchkick_index.clean_indices
|
data/test/match_test.rb
CHANGED
@@ -186,6 +186,11 @@ class MatchTest < Minitest::Test
|
|
186
186
|
assert_search "egg", ["eggs"], exclude: ["eggplant"], match: :word_start
|
187
187
|
end
|
188
188
|
|
189
|
+
def test_exclude_string
|
190
|
+
store_names ["Butter Tub", "Peanut Butter Tub"]
|
191
|
+
assert_search "butter", ["Butter Tub"], exclude: "peanut butter"
|
192
|
+
end
|
193
|
+
|
189
194
|
# other
|
190
195
|
|
191
196
|
def test_all
|
data/test/sql_test.rb
CHANGED
@@ -7,6 +7,11 @@ class SqlTest < Minitest::Test
|
|
7
7
|
assert_search "fresh honey", ["Honey"], operator: "or"
|
8
8
|
end
|
9
9
|
|
10
|
+
def test_operator_scoring
|
11
|
+
store_names ["Big Red Circle", "Big Green Circle", "Small Orange Circle"]
|
12
|
+
assert_order "big red circle", ["Big Red Circle", "Big Green Circle", "Small Orange Circle"], operator: "or"
|
13
|
+
end
|
14
|
+
|
10
15
|
def test_fields_operator
|
11
16
|
store [
|
12
17
|
{name: "red", color: "red"},
|
data/test/test_helper.rb
CHANGED
@@ -6,11 +6,16 @@ require "logger"
|
|
6
6
|
require "active_support/core_ext" if defined?(NoBrainer)
|
7
7
|
require "active_support/notifications"
|
8
8
|
|
9
|
+
Searchkick.index_suffix = ENV["TEST_ENV_NUMBER"]
|
10
|
+
|
9
11
|
ENV["RACK_ENV"] = "test"
|
10
12
|
|
11
13
|
Minitest::Test = Minitest::Unit::TestCase unless defined?(Minitest::Test)
|
12
14
|
|
13
|
-
|
15
|
+
if !defined?(ParallelTests) || ParallelTests.first_process?
|
16
|
+
File.delete("elasticsearch.log") if File.exist?("elasticsearch.log")
|
17
|
+
end
|
18
|
+
|
14
19
|
Searchkick.client.transport.logger = Logger.new("elasticsearch.log")
|
15
20
|
Searchkick.search_timeout = 5
|
16
21
|
|
@@ -466,7 +471,7 @@ class Animal
|
|
466
471
|
searchkick \
|
467
472
|
text_start: [:name],
|
468
473
|
suggest: [:name],
|
469
|
-
index_name: -> { "#{name.tableize}-#{Date.today.year}" },
|
474
|
+
index_name: -> { "#{name.tableize}-#{Date.today.year}#{Searchkick.index_suffix}" },
|
470
475
|
callbacks: defined?(ActiveJob) ? :async : true
|
471
476
|
# wordnet: true
|
472
477
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: searchkick
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.2.
|
4
|
+
version: 2.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -147,10 +147,12 @@ files:
|
|
147
147
|
- test/gemfiles/mongoid5.gemfile
|
148
148
|
- test/gemfiles/mongoid6.gemfile
|
149
149
|
- test/gemfiles/nobrainer.gemfile
|
150
|
+
- test/gemfiles/parallel_tests.gemfile
|
150
151
|
- test/geo_shape_test.rb
|
151
152
|
- test/highlight_test.rb
|
152
153
|
- test/index_test.rb
|
153
154
|
- test/inheritance_test.rb
|
155
|
+
- test/marshal_test.rb
|
154
156
|
- test/match_test.rb
|
155
157
|
- test/misspellings_test.rb
|
156
158
|
- test/model_test.rb
|
@@ -220,10 +222,12 @@ test_files:
|
|
220
222
|
- test/gemfiles/mongoid5.gemfile
|
221
223
|
- test/gemfiles/mongoid6.gemfile
|
222
224
|
- test/gemfiles/nobrainer.gemfile
|
225
|
+
- test/gemfiles/parallel_tests.gemfile
|
223
226
|
- test/geo_shape_test.rb
|
224
227
|
- test/highlight_test.rb
|
225
228
|
- test/index_test.rb
|
226
229
|
- test/inheritance_test.rb
|
230
|
+
- test/marshal_test.rb
|
227
231
|
- test/match_test.rb
|
228
232
|
- test/misspellings_test.rb
|
229
233
|
- test/model_test.rb
|