searchkick 0.7.7 → 0.7.8
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/CHANGELOG.md +7 -1
- data/README.md +39 -14
- data/lib/searchkick/query.rb +37 -18
- data/lib/searchkick/results.rb +6 -1
- data/lib/searchkick/version.rb +1 -1
- data/test/boost_test.rb +37 -0
- data/test/sql_test.rb +7 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb8ada9111159102b2327b5344afe0876aac137d
|
4
|
+
data.tar.gz: 3e3e655a723d06f6b741b0938d3fde6d02d5c7ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fdb99efc9149d644dd126456c9ab2e753a6f67a77feb90e07ad20dcbea75dd7152705136a2e30cfd0fd9e1a38a0ba35b1f05d0b8dd6c986ba248aa90a82126b2
|
7
|
+
data.tar.gz: 04a2c3229e5f40a866fa8cc2aed8832d361d680ef9a88fe75d1e3b8dc72875524961056f2f00bf2edd7bcd07989864118367547006198588b5f3af3e0e81ee96
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,13 @@
|
|
1
|
+
## 0.7.8
|
2
|
+
|
3
|
+
- Added `boost_by` and `boost_where` options
|
4
|
+
- Added ability to boost fields - `name^10`
|
5
|
+
- Added `select` option for `load: false`
|
6
|
+
|
1
7
|
## 0.7.7
|
2
8
|
|
3
9
|
- Added support for automatic failover
|
4
|
-
- Fixed default
|
10
|
+
- Fixed `operator` option (and default) for partial matches
|
5
11
|
|
6
12
|
## 0.7.6
|
7
13
|
|
data/README.md
CHANGED
@@ -116,10 +116,26 @@ Limit / offset
|
|
116
116
|
limit: 20, offset: 40
|
117
117
|
```
|
118
118
|
|
119
|
-
|
119
|
+
### Boosting
|
120
|
+
|
121
|
+
Boost important fields
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
fields: ["title^10", "description"]
|
125
|
+
```
|
126
|
+
|
127
|
+
Boost by the value of a field
|
120
128
|
|
121
129
|
```ruby
|
122
|
-
|
130
|
+
boost_by: [:orders_count] # give popular documents a little boost
|
131
|
+
boost_by: {orders_count: {factor: 10}}
|
132
|
+
```
|
133
|
+
|
134
|
+
Boost matching documents
|
135
|
+
|
136
|
+
```ruby
|
137
|
+
boost_where: {user_id: 1}
|
138
|
+
boost_where: {user_id: {value: 1, factor: 100}}
|
123
139
|
```
|
124
140
|
|
125
141
|
### Get Everything
|
@@ -164,7 +180,7 @@ class Product < ActiveRecord::Base
|
|
164
180
|
end
|
165
181
|
```
|
166
182
|
|
167
|
-
And to search:
|
183
|
+
And to search (after you reindex):
|
168
184
|
|
169
185
|
```ruby
|
170
186
|
Product.search "back", fields: [{name: :word_start}]
|
@@ -182,6 +198,12 @@ Available options are:
|
|
182
198
|
:text_end
|
183
199
|
```
|
184
200
|
|
201
|
+
To boost fields, use:
|
202
|
+
|
203
|
+
```ruby
|
204
|
+
fields: [{"name^2" => :word_start}] # better interface on the way
|
205
|
+
```
|
206
|
+
|
185
207
|
### Language
|
186
208
|
|
187
209
|
Searchkick defaults to English for stemming. To change this, use:
|
@@ -281,7 +303,7 @@ end
|
|
281
303
|
|
282
304
|
You do **not** need to clean up the search queries. Searchkick automatically treats `apple` and `APPLES` the same.
|
283
305
|
|
284
|
-
Next, add conversions to the index.
|
306
|
+
Next, add conversions to the index.
|
285
307
|
|
286
308
|
```ruby
|
287
309
|
class Product < ActiveRecord::Base
|
@@ -311,22 +333,21 @@ Order results differently for each user. For example, show a user’s previousl
|
|
311
333
|
|
312
334
|
```ruby
|
313
335
|
class Product < ActiveRecord::Base
|
314
|
-
searchkick personalize: "user_ids"
|
315
336
|
|
316
337
|
def search_data
|
317
338
|
{
|
318
339
|
name: name,
|
319
340
|
user_ids: orders.pluck(:user_id) # boost this product for these users
|
320
|
-
# [4, 8, 15, 16, 23, 42]
|
321
341
|
}
|
322
342
|
end
|
343
|
+
|
323
344
|
end
|
324
345
|
```
|
325
346
|
|
326
347
|
Reindex and search with:
|
327
348
|
|
328
349
|
```ruby
|
329
|
-
Product.search "milk", user_id: 8
|
350
|
+
Product.search "milk", boost_where: {user_id: 8}
|
330
351
|
```
|
331
352
|
|
332
353
|
### Autocomplete
|
@@ -484,8 +505,6 @@ product.similar(fields: ["name"])
|
|
484
505
|
|
485
506
|
### Geospatial Searches
|
486
507
|
|
487
|
-
**Note:** Before `0.3.0`, locations were indexed incorrectly. When upgrading, be sure to reindex immediately.
|
488
|
-
|
489
508
|
```ruby
|
490
509
|
class City < ActiveRecord::Base
|
491
510
|
searchkick locations: ["location"]
|
@@ -785,10 +804,20 @@ rake searchkick:reindex:all
|
|
785
804
|
|
786
805
|
4. Once it finishes, replace search calls w/ searchkick calls
|
787
806
|
|
788
|
-
##
|
807
|
+
## Upgrading
|
808
|
+
|
809
|
+
View the [changelog](https://github.com/ankane/searchkick/blob/master/CHANGELOG.md).
|
810
|
+
|
811
|
+
Important notes are listed below.
|
812
|
+
|
813
|
+
### 0.6.0 and 0.7.0
|
789
814
|
|
790
815
|
If running Searchkick `0.6.0` or `0.7.0` and Elasticsearch `0.90`, we recommend upgrading to Searchkick `0.6.1` or `0.7.1` to fix an issue that causes downtime when reindexing.
|
791
816
|
|
817
|
+
### 0.3.0
|
818
|
+
|
819
|
+
Before `0.3.0`, locations were indexed incorrectly. When upgrading, be sure to reindex immediately.
|
820
|
+
|
792
821
|
## Elasticsearch Gotchas
|
793
822
|
|
794
823
|
### Inconsistent Scores
|
@@ -816,10 +845,6 @@ Thanks to Karel Minarik for [Elasticsearch Ruby](https://github.com/elasticsearc
|
|
816
845
|
- Much finer customization
|
817
846
|
- More transparency into generated queries (for advanced use)
|
818
847
|
|
819
|
-
## History
|
820
|
-
|
821
|
-
View the [changelog](https://github.com/ankane/searchkick/blob/master/CHANGELOG.md)
|
822
|
-
|
823
848
|
## Contributing
|
824
849
|
|
825
850
|
Everyone is encouraged to help improve this project. Here are a few ways you can help:
|
data/lib/searchkick/query.rb
CHANGED
@@ -15,6 +15,7 @@ module Searchkick
|
|
15
15
|
@term = term
|
16
16
|
@options = options
|
17
17
|
|
18
|
+
boost_fields = {}
|
18
19
|
fields =
|
19
20
|
if options[:fields]
|
20
21
|
if options[:autocomplete]
|
@@ -22,7 +23,10 @@ module Searchkick
|
|
22
23
|
else
|
23
24
|
options[:fields].map do |value|
|
24
25
|
k, v = value.is_a?(Hash) ? value.to_a.first : [value, :word]
|
25
|
-
|
26
|
+
k2, boost = k.to_s.split("^", 2)
|
27
|
+
field = "#{k2}.#{v == :word ? "analyzed" : v}"
|
28
|
+
boost_fields[field] = boost.to_i if boost
|
29
|
+
field
|
26
30
|
end
|
27
31
|
end
|
28
32
|
else
|
@@ -74,17 +78,19 @@ module Searchkick
|
|
74
78
|
else
|
75
79
|
queries = []
|
76
80
|
fields.each do |field|
|
81
|
+
factor = boost_fields[field] || 1
|
77
82
|
shared_options = {
|
78
83
|
fields: [field],
|
79
84
|
query: term,
|
80
85
|
use_dis_max: false,
|
81
|
-
operator: operator
|
86
|
+
operator: operator,
|
87
|
+
boost: factor
|
82
88
|
}
|
83
89
|
if field == "_all" or field.end_with?(".analyzed")
|
84
90
|
shared_options[:cutoff_frequency] = 0.001 unless operator == "and"
|
85
91
|
queries.concat [
|
86
|
-
{multi_match: shared_options.merge(boost: 10, analyzer: "searchkick_search")},
|
87
|
-
{multi_match: shared_options.merge(boost: 10, analyzer: "searchkick_search2")}
|
92
|
+
{multi_match: shared_options.merge(boost: 10 * factor, analyzer: "searchkick_search")},
|
93
|
+
{multi_match: shared_options.merge(boost: 10 * factor, analyzer: "searchkick_search2")}
|
88
94
|
]
|
89
95
|
if options[:misspellings] != false
|
90
96
|
distance = (options[:misspellings].is_a?(Hash) && options[:misspellings][:distance]) || 1
|
@@ -137,36 +143,45 @@ module Searchkick
|
|
137
143
|
|
138
144
|
custom_filters = []
|
139
145
|
|
146
|
+
boost_by = options[:boost_by] || {}
|
147
|
+
if boost_by.is_a?(Array)
|
148
|
+
boost_by = Hash[ boost_by.map{|f| [f, {factor: 1}] } ]
|
149
|
+
end
|
140
150
|
if options[:boost]
|
151
|
+
boost_by[options[:boost]] = {factor: 1}
|
152
|
+
end
|
153
|
+
|
154
|
+
boost_by.each do |field, value|
|
141
155
|
custom_filters << {
|
142
156
|
filter: {
|
143
157
|
exists: {
|
144
|
-
field:
|
158
|
+
field: field
|
145
159
|
}
|
146
160
|
},
|
147
161
|
script_score: {
|
148
|
-
script: "log(doc['#{
|
162
|
+
script: "#{value[:factor].to_f} * log(doc['#{field}'].value + 2.718281828)"
|
149
163
|
}
|
150
164
|
}
|
151
165
|
end
|
152
166
|
|
167
|
+
boost_where = options[:boost_where] || {}
|
153
168
|
if options[:user_id] and personalize_field
|
154
|
-
|
155
|
-
filter: {
|
156
|
-
term: {
|
157
|
-
personalize_field => options[:user_id]
|
158
|
-
}
|
159
|
-
},
|
160
|
-
boost_factor: 100
|
161
|
-
}
|
169
|
+
boost_where[personalize_field] = options[:user_id]
|
162
170
|
end
|
163
|
-
|
164
171
|
if options[:personalize]
|
172
|
+
boost_where.merge!(options[:personalize])
|
173
|
+
end
|
174
|
+
boost_where.each do |field, value|
|
175
|
+
if value.is_a?(Hash)
|
176
|
+
value, factor = value[:value], value[:factor]
|
177
|
+
else
|
178
|
+
factor = 1000
|
179
|
+
end
|
165
180
|
custom_filters << {
|
166
181
|
filter: {
|
167
|
-
term:
|
182
|
+
term: {field => value}
|
168
183
|
},
|
169
|
-
boost_factor:
|
184
|
+
boost_factor: factor
|
170
185
|
}
|
171
186
|
end
|
172
187
|
|
@@ -292,7 +307,11 @@ module Searchkick
|
|
292
307
|
|
293
308
|
# An empty array will cause only the _id and _type for each hit to be returned
|
294
309
|
# http://www.elasticsearch.org/guide/reference/api/search/fields/
|
295
|
-
|
310
|
+
if load
|
311
|
+
payload[:fields] = []
|
312
|
+
elsif options[:select]
|
313
|
+
payload[:fields] = options[:select]
|
314
|
+
end
|
296
315
|
|
297
316
|
if options[:type] or klass != searchkick_klass
|
298
317
|
@type = [options[:type] || klass].flatten.map{|v| searchkick_index.klass_document_type(v) }
|
data/lib/searchkick/results.rb
CHANGED
@@ -38,7 +38,12 @@ module Searchkick
|
|
38
38
|
end.compact
|
39
39
|
else
|
40
40
|
hits.map do |hit|
|
41
|
-
result =
|
41
|
+
result =
|
42
|
+
if hit["_source"]
|
43
|
+
hit.except("_source").merge(hit["_source"])
|
44
|
+
else
|
45
|
+
hit.except("fields").merge(hit["fields"])
|
46
|
+
end
|
42
47
|
result["id"] ||= result["_id"] # needed for legacy reasons
|
43
48
|
Hashie::Mash.new(result)
|
44
49
|
end
|
data/lib/searchkick/version.rb
CHANGED
data/test/boost_test.rb
CHANGED
@@ -67,4 +67,41 @@ class TestBoost < Minitest::Unit::TestCase
|
|
67
67
|
assert_first "tomato", "Tomato B", personalize: {user_ids: 2}
|
68
68
|
end
|
69
69
|
|
70
|
+
def test_boost_fields
|
71
|
+
store [
|
72
|
+
{name: "Red", color: "White"},
|
73
|
+
{name: "White", color: "Red Red Red"}
|
74
|
+
]
|
75
|
+
assert_order "red", ["Red", "White"], fields: ["name^10", "color"]
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_boost_fields_word_start
|
79
|
+
store [
|
80
|
+
{name: "Red", color: "White"},
|
81
|
+
{name: "White", color: "Red Red Red"}
|
82
|
+
]
|
83
|
+
assert_order "red", ["Red", "White"], fields: [{"name^10" => :word_start}, "color"]
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_boost_by
|
87
|
+
store [
|
88
|
+
{name: "Tomato A"},
|
89
|
+
{name: "Tomato B", orders_count: 10},
|
90
|
+
{name: "Tomato C", orders_count: 100}
|
91
|
+
]
|
92
|
+
assert_order "tomato", ["Tomato C", "Tomato B", "Tomato A"], boost_by: [:orders_count]
|
93
|
+
assert_order "tomato", ["Tomato C", "Tomato B", "Tomato A"], boost_by: {orders_count: {factor: 10}}
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_boost_where
|
97
|
+
store [
|
98
|
+
{name: "Tomato A"},
|
99
|
+
{name: "Tomato B", user_ids: [1, 2, 3]},
|
100
|
+
{name: "Tomato C"},
|
101
|
+
{name: "Tomato D"}
|
102
|
+
]
|
103
|
+
assert_first "tomato", "Tomato B", boost_where: {user_ids: 2}
|
104
|
+
assert_first "tomato", "Tomato B", boost_where: {user_ids: {value: 2, factor: 10}}
|
105
|
+
end
|
106
|
+
|
70
107
|
end
|
data/test/sql_test.rb
CHANGED
@@ -274,6 +274,13 @@ class TestSql < Minitest::Unit::TestCase
|
|
274
274
|
assert_kind_of Hash, Product.search("product", load: false, include: [:store]).first
|
275
275
|
end
|
276
276
|
|
277
|
+
# select
|
278
|
+
|
279
|
+
def test_select
|
280
|
+
store [{name: "Product A", store_id: 1}]
|
281
|
+
assert_equal %w[id name store_id], Product.search("product", load: false, select: [:name, :store_id]).first.keys.reject{|k| k.start_with?("_") }.sort
|
282
|
+
end
|
283
|
+
|
277
284
|
# TODO see if Mongoid is loaded
|
278
285
|
if !defined?(Mongoid)
|
279
286
|
def test_include
|
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: 0.7.
|
4
|
+
version: 0.7.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-06-
|
11
|
+
date: 2014-06-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|