searchkick 1.3.1 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.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
|