searchkick 1.3.1 → 1.3.2
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/Gemfile +1 -1
- data/README.md +58 -8
- data/lib/searchkick.rb +4 -2
- data/lib/searchkick/index.rb +6 -5
- data/lib/searchkick/query.rb +57 -26
- data/lib/searchkick/version.rb +1 -1
- data/test/aggs_test.rb +23 -0
- data/test/boost_test.rb +25 -0
- data/test/errors_test.rb +19 -0
- data/test/gemfiles/{activerecord50.gemfile → activerecord42.gemfile} +1 -1
- data/test/gemfiles/nobrainer.gemfile +1 -1
- data/test/query_test.rb +10 -0
- data/test/sql_test.rb +7 -0
- data/test/test_helper.rb +41 -1
- metadata +23 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e749d5351a6a6132cf79bb8294ad8e86c72968b0
|
4
|
+
data.tar.gz: d6ebce4be756ff0cbd9ac60653b95c9e0aaddbba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a31724df713fd03b8ddabd57ffd16c1b346023a003a5bf6fcaa6be4578d19f4480fb3eee94e9863c1cd5179bca9ef17ee67a7503c18f9a3a7af64930ee65e6ac
|
7
|
+
data.tar.gz: 76bf046bc1a442cc8c209613512d5aad192fd6eb428dadf5d48fcacc9a6e4a87600701a6e0cdfb58bf4df542a9650e264d446a1a6bf496d6b3220866f3960a2e
|
data/.travis.yml
CHANGED
@@ -14,7 +14,7 @@ notifications:
|
|
14
14
|
on_failure: change
|
15
15
|
gemfile:
|
16
16
|
- Gemfile
|
17
|
-
- test/gemfiles/
|
17
|
+
- test/gemfiles/activerecord42.gemfile
|
18
18
|
- test/gemfiles/activerecord41.gemfile
|
19
19
|
- test/gemfiles/activerecord40.gemfile
|
20
20
|
- test/gemfiles/activerecord32.gemfile
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -472,7 +472,7 @@ Next, add conversions to the index.
|
|
472
472
|
class Product < ActiveRecord::Base
|
473
473
|
has_many :searches, class_name: "Searchjoy::Search"
|
474
474
|
|
475
|
-
searchkick conversions: "conversions" # name of field
|
475
|
+
searchkick conversions: ["conversions"] # name of field
|
476
476
|
|
477
477
|
def search_data
|
478
478
|
{
|
@@ -643,6 +643,12 @@ Minimum document count
|
|
643
643
|
Product.search "apples", aggs: {store_id: {min_doc_count: 2}}
|
644
644
|
```
|
645
645
|
|
646
|
+
Date histogram
|
647
|
+
|
648
|
+
```ruby
|
649
|
+
Product.search "pear", aggs: {products_per_year: {date_histogram: {field: :created_at, interval: :year}}}
|
650
|
+
```
|
651
|
+
|
646
652
|
#### Moving From Facets
|
647
653
|
|
648
654
|
1. Replace `facets` with `aggs` in searches. **Note:** Stats facets are not supported at this time.
|
@@ -1068,6 +1074,7 @@ class Product < ActiveRecord::Base
|
|
1068
1074
|
}
|
1069
1075
|
end
|
1070
1076
|
```
|
1077
|
+
**Note:** If you use a custom mapping, you'll need to use [custom searching](#advanced-search) as well.
|
1071
1078
|
|
1072
1079
|
To keep the mappings and settings generated by Searchkick, use:
|
1073
1080
|
|
@@ -1095,10 +1102,16 @@ products.response
|
|
1095
1102
|
|
1096
1103
|
To modify the query generated by Searchkick, use:
|
1097
1104
|
|
1105
|
+
```ruby
|
1106
|
+
products = Product.search "milk", body_options: {min_score: 1}
|
1107
|
+
```
|
1108
|
+
|
1109
|
+
or
|
1110
|
+
|
1098
1111
|
```ruby
|
1099
1112
|
products =
|
1100
1113
|
Product.search "apples" do |body|
|
1101
|
-
body[:
|
1114
|
+
body[:min_score] = 1
|
1102
1115
|
end
|
1103
1116
|
```
|
1104
1117
|
|
@@ -1116,6 +1129,20 @@ Then use `fresh_products` and `frozen_products` as typical results.
|
|
1116
1129
|
|
1117
1130
|
**Note:** Errors are not raised as with single requests. Use the `error` method on each query to check for errors. Also, if you use the `below` option for misspellings, misspellings will be disabled.
|
1118
1131
|
|
1132
|
+
### Multiple Indices
|
1133
|
+
|
1134
|
+
Search across multiple indices with:
|
1135
|
+
|
1136
|
+
```ruby
|
1137
|
+
Searchkick.search "milk", index_name: [Product, Category]
|
1138
|
+
```
|
1139
|
+
|
1140
|
+
Boost specific indices with:
|
1141
|
+
|
1142
|
+
```ruby
|
1143
|
+
indices_boost: {Category => 2, Product => 1}
|
1144
|
+
```
|
1145
|
+
|
1119
1146
|
## Reference
|
1120
1147
|
|
1121
1148
|
Reindex one record
|
@@ -1184,6 +1211,35 @@ class Product < ActiveRecord::Base
|
|
1184
1211
|
end
|
1185
1212
|
```
|
1186
1213
|
|
1214
|
+
Multiple conversion fields
|
1215
|
+
|
1216
|
+
```ruby
|
1217
|
+
class Product < ActiveRecord::Base
|
1218
|
+
has_many :searches, class_name: "Searchjoy::Search"
|
1219
|
+
|
1220
|
+
# searchkick also supports multiple "conversions" fields
|
1221
|
+
searchkick conversions: ["unique_user_conversions", "total_conversions"]
|
1222
|
+
|
1223
|
+
def search_data
|
1224
|
+
{
|
1225
|
+
name: name,
|
1226
|
+
unique_user_conversions: searches.group(:query).uniq.count(:user_id)
|
1227
|
+
# {"ice cream" => 234, "chocolate" => 67, "cream" => 2}
|
1228
|
+
total_conversions: searches.group(:query).count
|
1229
|
+
# {"ice cream" => 412, "chocolate" => 117, "cream" => 6}
|
1230
|
+
}
|
1231
|
+
end
|
1232
|
+
end
|
1233
|
+
```
|
1234
|
+
|
1235
|
+
and during query time:
|
1236
|
+
|
1237
|
+
```ruby
|
1238
|
+
Product.search("banana") # boost by both fields (default)
|
1239
|
+
Product.search("banana", conversions: "total_conversions") # only boost by total_conversions
|
1240
|
+
Product.search("banana", conversions: false) # no conversion boosting
|
1241
|
+
```
|
1242
|
+
|
1187
1243
|
Change timeout
|
1188
1244
|
|
1189
1245
|
```ruby
|
@@ -1274,12 +1330,6 @@ class Product < ActiveRecord::Base
|
|
1274
1330
|
end
|
1275
1331
|
```
|
1276
1332
|
|
1277
|
-
Search multiple models
|
1278
|
-
|
1279
|
-
```ruby
|
1280
|
-
Searchkick.search "milk", index_name: [Product, Category]
|
1281
|
-
```
|
1282
|
-
|
1283
1333
|
Reindex all models - Rails only
|
1284
1334
|
|
1285
1335
|
```sh
|
data/lib/searchkick.rb
CHANGED
@@ -107,8 +107,10 @@ module Searchkick
|
|
107
107
|
if items.any?
|
108
108
|
response = client.bulk(body: items)
|
109
109
|
if response["errors"]
|
110
|
-
|
111
|
-
|
110
|
+
first_with_error = response["items"].map do |item|
|
111
|
+
(item["index"] || item["delete"])
|
112
|
+
end.find { |item| item["error"] }
|
113
|
+
raise Searchkick::ImportError, "#{first_with_error["error"]} on item with id '#{first_with_error["_id"]}'"
|
112
114
|
end
|
113
115
|
end
|
114
116
|
end
|
data/lib/searchkick/index.rb
CHANGED
@@ -430,7 +430,7 @@ module Searchkick
|
|
430
430
|
mapping = {}
|
431
431
|
|
432
432
|
# conversions
|
433
|
-
|
433
|
+
Array(options[:conversions]).each do |conversions_field|
|
434
434
|
mapping[conversions_field] = {
|
435
435
|
type: "nested",
|
436
436
|
properties: {
|
@@ -570,7 +570,7 @@ module Searchkick
|
|
570
570
|
if klass.respond_to?(:document_type)
|
571
571
|
klass.document_type
|
572
572
|
else
|
573
|
-
klass.model_name.
|
573
|
+
klass.model_name.singular
|
574
574
|
end
|
575
575
|
end
|
576
576
|
|
@@ -602,9 +602,10 @@ module Searchkick
|
|
602
602
|
source = source.inject({}) { |memo, (k, v)| memo[k.to_s] = v; memo }.except("_id")
|
603
603
|
|
604
604
|
# conversions
|
605
|
-
|
606
|
-
|
607
|
-
|
605
|
+
Array(options[:conversions]).each do |conversions_field|
|
606
|
+
if source[conversions_field]
|
607
|
+
source[conversions_field] = source[conversions_field].map { |k, v| {query: k, count: v} }
|
608
|
+
end
|
608
609
|
end
|
609
610
|
|
610
611
|
# hack to prevent generator field doesn't exist error
|
data/lib/searchkick/query.rb
CHANGED
@@ -162,8 +162,8 @@ module Searchkick
|
|
162
162
|
# model and eagar loading
|
163
163
|
load = options[:load].nil? ? true : options[:load]
|
164
164
|
|
165
|
-
|
166
|
-
personalize_field
|
165
|
+
conversions_fields = Array(options[:conversions] || searchkick_options[:conversions])
|
166
|
+
personalize_field = searchkick_options[:personalize]
|
167
167
|
|
168
168
|
all = term == "*"
|
169
169
|
|
@@ -275,34 +275,38 @@ module Searchkick
|
|
275
275
|
}
|
276
276
|
end
|
277
277
|
|
278
|
-
if
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
278
|
+
if conversions_fields.present? && options[:conversions] != false
|
279
|
+
shoulds = []
|
280
|
+
conversions_fields.each do |conversions_field|
|
281
|
+
# wrap payload in a bool query
|
282
|
+
script_score =
|
283
|
+
if below12?
|
284
|
+
{script_score: {script: "doc['count'].value"}}
|
285
|
+
else
|
286
|
+
{field_value_factor: {field: "#{conversions_field}.count"}}
|
287
|
+
end
|
286
288
|
|
289
|
+
shoulds << {
|
290
|
+
nested: {
|
291
|
+
path: conversions_field,
|
292
|
+
score_mode: "sum",
|
293
|
+
query: {
|
294
|
+
function_score: {
|
295
|
+
boost_mode: "replace",
|
296
|
+
query: {
|
297
|
+
match: {
|
298
|
+
"#{conversions_field}.query" => term
|
299
|
+
}
|
300
|
+
}
|
301
|
+
}.merge(script_score)
|
302
|
+
}
|
303
|
+
}
|
304
|
+
}
|
305
|
+
end
|
287
306
|
payload = {
|
288
307
|
bool: {
|
289
308
|
must: payload,
|
290
|
-
should:
|
291
|
-
nested: {
|
292
|
-
path: conversions_field,
|
293
|
-
score_mode: "sum",
|
294
|
-
query: {
|
295
|
-
function_score: {
|
296
|
-
boost_mode: "replace",
|
297
|
-
query: {
|
298
|
-
match: {
|
299
|
-
"#{conversions_field}.query" => term
|
300
|
-
}
|
301
|
-
}
|
302
|
-
}.merge(script_score)
|
303
|
-
}
|
304
|
-
}
|
305
|
-
}
|
309
|
+
should: shoulds
|
306
310
|
}
|
307
311
|
}
|
308
312
|
end
|
@@ -345,6 +349,9 @@ module Searchkick
|
|
345
349
|
# order
|
346
350
|
set_order(payload) if options[:order]
|
347
351
|
|
352
|
+
# indices_boost
|
353
|
+
set_boost_by_indices(payload)
|
354
|
+
|
348
355
|
# filters
|
349
356
|
filters = where_filters(options[:where])
|
350
357
|
set_filters(payload, filters) if filters.any?
|
@@ -385,6 +392,9 @@ module Searchkick
|
|
385
392
|
@routing = options[:routing] if options[:routing]
|
386
393
|
end
|
387
394
|
|
395
|
+
# merge more body options
|
396
|
+
payload = payload.deep_merge(options[:body_options]) if options[:body_options]
|
397
|
+
|
388
398
|
@body = payload
|
389
399
|
@facet_limits = @facet_limits || {}
|
390
400
|
@page = page
|
@@ -469,6 +479,19 @@ module Searchkick
|
|
469
479
|
end
|
470
480
|
end
|
471
481
|
|
482
|
+
def set_boost_by_indices(payload)
|
483
|
+
return unless options[:indices_boost]
|
484
|
+
|
485
|
+
indices_boost = options[:indices_boost].each_with_object({}) do |(key, boost), memo|
|
486
|
+
index = key.respond_to?(:searchkick_index) ? key.searchkick_index.name : key
|
487
|
+
# try to use index explicitly instead of alias: https://github.com/elasticsearch/elasticsearch/issues/4756
|
488
|
+
index_by_alias = Searchkick.client.indices.get_alias(index: index).keys.first
|
489
|
+
memo[index_by_alias || index] = boost
|
490
|
+
end
|
491
|
+
|
492
|
+
payload[:indices_boost] = indices_boost
|
493
|
+
end
|
494
|
+
|
472
495
|
def set_suggestions(payload)
|
473
496
|
suggest_fields = (searchkick_options[:suggest] || []).map(&:to_s)
|
474
497
|
|
@@ -544,6 +567,14 @@ module Searchkick
|
|
544
567
|
ranges: agg_options[:date_ranges]
|
545
568
|
}.merge(shared_agg_options)
|
546
569
|
}
|
570
|
+
elsif histogram = agg_options[:date_histogram]
|
571
|
+
interval = histogram[:interval]
|
572
|
+
payload[:aggs][field] = {
|
573
|
+
date_histogram: {
|
574
|
+
field: histogram[:field],
|
575
|
+
interval: interval
|
576
|
+
}
|
577
|
+
}
|
547
578
|
else
|
548
579
|
payload[:aggs][field] = {
|
549
580
|
terms: {
|
data/lib/searchkick/version.rb
CHANGED
data/test/aggs_test.rb
CHANGED
@@ -96,6 +96,29 @@ class AggsTest < Minitest::Test
|
|
96
96
|
assert_equal ({2 => 2}), store_agg(where: {color: "blue"}, aggs: {store_id: {where: {in_stock: false}}}, smart_aggs: false)
|
97
97
|
end
|
98
98
|
|
99
|
+
def test_aggs_group_by_date
|
100
|
+
store [{name: "Old Product", created_at: 3.years.ago}]
|
101
|
+
aggs = Product.search(
|
102
|
+
"Product",
|
103
|
+
{
|
104
|
+
aggs: {
|
105
|
+
products_per_year: {
|
106
|
+
date_histogram: {
|
107
|
+
field: :created_at,
|
108
|
+
interval: :year
|
109
|
+
}
|
110
|
+
}
|
111
|
+
}
|
112
|
+
}
|
113
|
+
).aggs
|
114
|
+
|
115
|
+
if elasticsearch_below20?
|
116
|
+
assert_equal 2, aggs["products_per_year"]["buckets"].size
|
117
|
+
else
|
118
|
+
assert_equal 4, aggs["products_per_year"]["buckets"].size
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
99
122
|
protected
|
100
123
|
|
101
124
|
def buckets_as_hash(agg)
|
data/test/boost_test.rb
CHANGED
@@ -10,6 +10,24 @@ class BoostTest < Minitest::Test
|
|
10
10
|
{name: "Tomato C", conversions: {"tomato" => 3}}
|
11
11
|
]
|
12
12
|
assert_order "tomato", ["Tomato C", "Tomato B", "Tomato A"]
|
13
|
+
assert_equal_scores "tomato", {conversions: false}
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_multiple_conversions
|
17
|
+
skip if elasticsearch_below14?
|
18
|
+
|
19
|
+
store [
|
20
|
+
{name: "Speaker A", conversions_a: {"speaker" => 1}, conversions_b: {"speaker" => 6}},
|
21
|
+
{name: "Speaker B", conversions_a: {"speaker" => 2}, conversions_b: {"speaker" => 5}},
|
22
|
+
{name: "Speaker C", conversions_a: {"speaker" => 3}, conversions_b: {"speaker" => 4}},
|
23
|
+
], Speaker
|
24
|
+
|
25
|
+
assert_equal_scores "speaker", {conversions: false}, Speaker
|
26
|
+
assert_equal_scores "speaker", {}, Speaker
|
27
|
+
assert_equal_scores "speaker", {conversions: ["conversions_a", "conversions_b"]}, Speaker
|
28
|
+
assert_equal_scores "speaker", {conversions: ["conversions_b", "conversions_a"]}, Speaker
|
29
|
+
assert_order "speaker", ["Speaker C", "Speaker B", "Speaker A"], {conversions: "conversions_a"}, Speaker
|
30
|
+
assert_order "speaker", ["Speaker A", "Speaker B", "Speaker C"], {conversions: "conversions_b"}, Speaker
|
13
31
|
end
|
14
32
|
|
15
33
|
def test_conversions_stemmed
|
@@ -141,4 +159,11 @@ class BoostTest < Minitest::Test
|
|
141
159
|
]
|
142
160
|
assert_order "san", ["San Francisco", "San Antonio", "San Marino"], boost_by_distance: {field: :location, origin: {lat: 37, lon: -122}, scale: "1000mi"}
|
143
161
|
end
|
162
|
+
|
163
|
+
def test_boost_by_indices
|
164
|
+
store_names ["Rex"], Animal
|
165
|
+
store_names ["Rexx"], Product
|
166
|
+
|
167
|
+
assert_order "Rex", ["Rexx", "Rex"], {index_name: [Animal, Product], indices_boost: {Animal => 1, Product => 200}}, Store
|
168
|
+
end
|
144
169
|
end
|
data/test/errors_test.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require_relative "test_helper"
|
2
|
+
|
3
|
+
class ErrorsTest < Minitest::Test
|
4
|
+
def test_bulk_import_raises_error
|
5
|
+
valid_dog = Dog.new(name: "2016-01-02")
|
6
|
+
invalid_dog = Dog.new(name: "Ol' One-Leg")
|
7
|
+
index = Searchkick::Index.new "dogs", mappings: {
|
8
|
+
dog: {
|
9
|
+
properties: {
|
10
|
+
name: {type: "date"}
|
11
|
+
}
|
12
|
+
}
|
13
|
+
}
|
14
|
+
index.store valid_dog
|
15
|
+
error = assert_raises(Searchkick::ImportError) do
|
16
|
+
index.bulk_index [valid_dog, invalid_dog]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/test/query_test.rb
CHANGED
@@ -10,4 +10,14 @@ class QueryTest < Minitest::Test
|
|
10
10
|
assert_equal ["Apple", "Milk"], query.map(&:name).sort
|
11
11
|
assert_equal ["Apple", "Milk"], query.execute.map(&:name).sort
|
12
12
|
end
|
13
|
+
|
14
|
+
def test_with_effective_min_score
|
15
|
+
store_names ["Milk", "Milk2"]
|
16
|
+
assert_equal ["Milk"], Product.search("Milk", body_options: { min_score: 0.1 }).map(&:name)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_with_uneffective_min_score
|
20
|
+
store_names ["Milk", "Milk2"]
|
21
|
+
assert_equal ["Milk", "Milk2"], Product.search("Milk", body_options: { min_score: 0.0001 }).map(&:name)
|
22
|
+
end
|
13
23
|
end
|
data/test/sql_test.rb
CHANGED
@@ -52,6 +52,13 @@ class SqlTest < Minitest::Test
|
|
52
52
|
assert_search "product", ["Product"], where: {latitude: {gt: 79}}
|
53
53
|
end
|
54
54
|
|
55
|
+
# body_options
|
56
|
+
|
57
|
+
def test_body_options_should_merge_into_body
|
58
|
+
query = Product.search({ query: { name: "milk"}, body_options: { min_score: 1.0 }}, execute: false)
|
59
|
+
assert_equal 1.0, query.body[:min_score]
|
60
|
+
end
|
61
|
+
|
55
62
|
# load
|
56
63
|
|
57
64
|
def test_load_default
|
data/test/test_helper.rb
CHANGED
@@ -93,6 +93,12 @@ if defined?(Mongoid)
|
|
93
93
|
field :name
|
94
94
|
end
|
95
95
|
|
96
|
+
class Speaker
|
97
|
+
include Mongoid::Document
|
98
|
+
|
99
|
+
field :name
|
100
|
+
end
|
101
|
+
|
96
102
|
class Animal
|
97
103
|
include Mongoid::Document
|
98
104
|
|
@@ -137,6 +143,13 @@ elsif defined?(NoBrainer)
|
|
137
143
|
field :name, type: String
|
138
144
|
end
|
139
145
|
|
146
|
+
class Speaker
|
147
|
+
include NoBrainer::Document
|
148
|
+
|
149
|
+
field :id, type: Object
|
150
|
+
field :name, type: String
|
151
|
+
end
|
152
|
+
|
140
153
|
class Animal
|
141
154
|
include NoBrainer::Document
|
142
155
|
|
@@ -162,7 +175,7 @@ else
|
|
162
175
|
# migrations
|
163
176
|
ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
|
164
177
|
|
165
|
-
ActiveRecord::Base.raise_in_transactional_callbacks = true if ActiveRecord::
|
178
|
+
ActiveRecord::Base.raise_in_transactional_callbacks = true if ActiveRecord::VERSION::STRING.start_with?("4.2.")
|
166
179
|
|
167
180
|
if defined?(Apartment)
|
168
181
|
class Rails
|
@@ -221,6 +234,10 @@ else
|
|
221
234
|
t.string :name
|
222
235
|
end
|
223
236
|
|
237
|
+
ActiveRecord::Migration.create_table :speakers do |t|
|
238
|
+
t.string :name
|
239
|
+
end
|
240
|
+
|
224
241
|
ActiveRecord::Migration.create_table :animals do |t|
|
225
242
|
t.string :name
|
226
243
|
t.string :type
|
@@ -233,6 +250,9 @@ else
|
|
233
250
|
has_many :products
|
234
251
|
end
|
235
252
|
|
253
|
+
class Speaker < ActiveRecord::Base
|
254
|
+
end
|
255
|
+
|
236
256
|
class Animal < ActiveRecord::Base
|
237
257
|
end
|
238
258
|
|
@@ -310,6 +330,20 @@ class Store
|
|
310
330
|
end
|
311
331
|
end
|
312
332
|
|
333
|
+
class Speaker
|
334
|
+
searchkick \
|
335
|
+
conversions: ["conversions_a", "conversions_b"]
|
336
|
+
|
337
|
+
attr_accessor :conversions_a, :conversions_b
|
338
|
+
|
339
|
+
def search_data
|
340
|
+
serializable_hash.except("id").merge(
|
341
|
+
conversions_a: conversions_a,
|
342
|
+
conversions_b: conversions_b,
|
343
|
+
)
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
313
347
|
class Animal
|
314
348
|
searchkick \
|
315
349
|
autocomplete: [:name],
|
@@ -325,12 +359,14 @@ Product.create!(name: "Set mapping")
|
|
325
359
|
|
326
360
|
Store.reindex
|
327
361
|
Animal.reindex
|
362
|
+
Speaker.reindex
|
328
363
|
|
329
364
|
class Minitest::Test
|
330
365
|
def setup
|
331
366
|
Product.destroy_all
|
332
367
|
Store.destroy_all
|
333
368
|
Animal.destroy_all
|
369
|
+
Speaker.destroy_all
|
334
370
|
end
|
335
371
|
|
336
372
|
protected
|
@@ -355,6 +391,10 @@ class Minitest::Test
|
|
355
391
|
assert_equal expected, klass.search(term, options).map(&:name)
|
356
392
|
end
|
357
393
|
|
394
|
+
def assert_equal_scores(term, options = {}, klass = Product)
|
395
|
+
assert_equal 1, klass.search(term, options).hits.map { |a| a['_score'] }.uniq.size
|
396
|
+
end
|
397
|
+
|
358
398
|
def assert_first(term, expected, options = {}, klass = Product)
|
359
399
|
assert_equal expected, klass.search(term, options).map(&:name).first
|
360
400
|
end
|
metadata
CHANGED
@@ -1,97 +1,97 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: searchkick
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-08-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: elasticsearch
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '1'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: hashie
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: bundler
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - ~>
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '1.6'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - ~>
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '1.6'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rake
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: minitest
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
description: Intelligent search made easy
|
@@ -101,8 +101,8 @@ executables: []
|
|
101
101
|
extensions: []
|
102
102
|
extra_rdoc_files: []
|
103
103
|
files:
|
104
|
-
- .gitignore
|
105
|
-
- .travis.yml
|
104
|
+
- ".gitignore"
|
105
|
+
- ".travis.yml"
|
106
106
|
- CHANGELOG.md
|
107
107
|
- Gemfile
|
108
108
|
- LICENSE.txt
|
@@ -126,12 +126,13 @@ files:
|
|
126
126
|
- test/callbacks_test.rb
|
127
127
|
- test/ci/before_install.sh
|
128
128
|
- test/dangerous_reindex_test.rb
|
129
|
+
- test/errors_test.rb
|
129
130
|
- test/facets_test.rb
|
130
131
|
- test/gemfiles/activerecord31.gemfile
|
131
132
|
- test/gemfiles/activerecord32.gemfile
|
132
133
|
- test/gemfiles/activerecord40.gemfile
|
133
134
|
- test/gemfiles/activerecord41.gemfile
|
134
|
-
- test/gemfiles/
|
135
|
+
- test/gemfiles/activerecord42.gemfile
|
135
136
|
- test/gemfiles/apartment.gemfile
|
136
137
|
- test/gemfiles/mongoid2.gemfile
|
137
138
|
- test/gemfiles/mongoid3.gemfile
|
@@ -170,17 +171,17 @@ require_paths:
|
|
170
171
|
- lib
|
171
172
|
required_ruby_version: !ruby/object:Gem::Requirement
|
172
173
|
requirements:
|
173
|
-
- -
|
174
|
+
- - ">="
|
174
175
|
- !ruby/object:Gem::Version
|
175
176
|
version: '0'
|
176
177
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
177
178
|
requirements:
|
178
|
-
- -
|
179
|
+
- - ">="
|
179
180
|
- !ruby/object:Gem::Version
|
180
181
|
version: '0'
|
181
182
|
requirements: []
|
182
183
|
rubyforge_project:
|
183
|
-
rubygems_version: 2.
|
184
|
+
rubygems_version: 2.6.1
|
184
185
|
signing_key:
|
185
186
|
specification_version: 4
|
186
187
|
summary: Searchkick learns what your users are looking for. As more people search,
|
@@ -193,12 +194,13 @@ test_files:
|
|
193
194
|
- test/callbacks_test.rb
|
194
195
|
- test/ci/before_install.sh
|
195
196
|
- test/dangerous_reindex_test.rb
|
197
|
+
- test/errors_test.rb
|
196
198
|
- test/facets_test.rb
|
197
199
|
- test/gemfiles/activerecord31.gemfile
|
198
200
|
- test/gemfiles/activerecord32.gemfile
|
199
201
|
- test/gemfiles/activerecord40.gemfile
|
200
202
|
- test/gemfiles/activerecord41.gemfile
|
201
|
-
- test/gemfiles/
|
203
|
+
- test/gemfiles/activerecord42.gemfile
|
202
204
|
- test/gemfiles/apartment.gemfile
|
203
205
|
- test/gemfiles/mongoid2.gemfile
|
204
206
|
- test/gemfiles/mongoid3.gemfile
|