searchkick 0.3.3 → 0.3.4
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 +6 -0
- data/README.md +33 -4
- data/lib/searchkick/model.rb +23 -0
- data/lib/searchkick/reindex.rb +2 -0
- data/lib/searchkick/results.rb +10 -0
- data/lib/searchkick/search.rb +14 -2
- data/lib/searchkick/tasks.rb +2 -0
- data/lib/searchkick/version.rb +1 -1
- data/test/highlight_test.rb +22 -0
- data/test/sql_test.rb +12 -0
- data/test/suggest_test.rb +3 -3
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d67265d1ad299d9e79b7f1020197f3b12f551535
|
4
|
+
data.tar.gz: b72d9fb064fad2f904db6d2cf69e9be96fb8c44e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ec7b5537539de163009b0857bd84a78829a0520b55b1f77544d0a65dee789dfce467b7afc63aa4aa54327d87be1dc3954178d3d209a35bb92e47c5179ad53a3
|
7
|
+
data.tar.gz: c9710769dd1045f5e8cfb1cd4cc86242df365289d28409bf8c47fe19e3b829b6d5b7ab6bed8ba890e56189ececacad520280c0940651bb2d8cdb2a0f78ac1356
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -29,7 +29,7 @@ Plus:
|
|
29
29
|
|
30
30
|
## Get Started
|
31
31
|
|
32
|
-
[Install Elasticsearch](http://www.elasticsearch.org/guide/reference/setup
|
32
|
+
[Install Elasticsearch](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/setup.html). For Homebrew, use:
|
33
33
|
|
34
34
|
```sh
|
35
35
|
brew install elasticsearch
|
@@ -152,7 +152,13 @@ Call `Product.reindex` after changing synonyms.
|
|
152
152
|
By default, Searchkick handles misspelled queries by returning results with an [edit distance](http://en.wikipedia.org/wiki/Levenshtein_distance) of one. To turn off this feature, use:
|
153
153
|
|
154
154
|
```ruby
|
155
|
-
Product.search "zuchini", misspellings: false
|
155
|
+
Product.search "zuchini", misspellings: false # no zucchini
|
156
|
+
```
|
157
|
+
|
158
|
+
You can also change the edit distance with:
|
159
|
+
|
160
|
+
```ruby
|
161
|
+
Product.search "zucini", misspellings: {distance: 2} # zucchini
|
156
162
|
```
|
157
163
|
|
158
164
|
### Indexing
|
@@ -342,6 +348,30 @@ Advanced
|
|
342
348
|
Product.search "2% Milk", facets: {store_id: {where: {in_stock: true}, limit: 10}}
|
343
349
|
```
|
344
350
|
|
351
|
+
### Highlight
|
352
|
+
|
353
|
+
Highlight the search query in the results.
|
354
|
+
|
355
|
+
```ruby
|
356
|
+
bands = Band.search "cinema", fields: [:name], highlight: true
|
357
|
+
```
|
358
|
+
|
359
|
+
**Note:** The `fields` option is required.
|
360
|
+
|
361
|
+
View the highlighted fields with:
|
362
|
+
|
363
|
+
```ruby
|
364
|
+
bands.with_details.each do |band, details|
|
365
|
+
puts details[:highlight][:name] # "Two Door <em>Cinema</em> Club"
|
366
|
+
end
|
367
|
+
```
|
368
|
+
|
369
|
+
To change the tag, use:
|
370
|
+
|
371
|
+
```ruby
|
372
|
+
Band.search "cinema", fields: [:name], highlight: {tag: "<strong>"}
|
373
|
+
```
|
374
|
+
|
345
375
|
### Similar Items
|
346
376
|
|
347
377
|
Find similar items.
|
@@ -528,7 +558,7 @@ rake searchkick:reindex:all
|
|
528
558
|
|
529
559
|
```ruby
|
530
560
|
class Product < ActiveRecord::Base
|
531
|
-
|
561
|
+
searchkick
|
532
562
|
end
|
533
563
|
```
|
534
564
|
|
@@ -560,7 +590,6 @@ Thanks to Karel Minarik for [Tire](https://github.com/karmi/tire), Jaroslav Kali
|
|
560
590
|
|
561
591
|
## TODO
|
562
592
|
|
563
|
-
- Analytics for searches and conversions
|
564
593
|
- Generate autocomplete predictions from past search queries
|
565
594
|
- Automatic failover
|
566
595
|
- Make Searchkick work with any language
|
data/lib/searchkick/model.rb
CHANGED
@@ -61,6 +61,29 @@ module Searchkick
|
|
61
61
|
source[field] = source[field].map(&:to_f).reverse if source[field]
|
62
62
|
end
|
63
63
|
|
64
|
+
# change all BigDecimal values to floats due to
|
65
|
+
# https://github.com/rails/rails/issues/6033
|
66
|
+
# possible loss of precision :/
|
67
|
+
cast_big_decimal =
|
68
|
+
proc do |obj|
|
69
|
+
case obj
|
70
|
+
when BigDecimal
|
71
|
+
obj.to_f
|
72
|
+
when Hash
|
73
|
+
obj.each do |k, v|
|
74
|
+
obj[k] = cast_big_decimal.call(v)
|
75
|
+
end
|
76
|
+
when Enumerable
|
77
|
+
obj.map! do |v|
|
78
|
+
cast_big_decimal.call(v)
|
79
|
+
end
|
80
|
+
else
|
81
|
+
obj
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
cast_big_decimal.call(source)
|
86
|
+
|
64
87
|
source.to_json
|
65
88
|
end
|
66
89
|
|
data/lib/searchkick/reindex.rb
CHANGED
@@ -203,6 +203,8 @@ module Searchkick
|
|
203
203
|
fields: {
|
204
204
|
field => {type: "string", index: "not_analyzed"},
|
205
205
|
"analyzed" => {type: "string", index: "analyzed"}
|
206
|
+
# term_vector: "with_positions_offsets" for fast / correct highlighting
|
207
|
+
# http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-highlighting.html#_fast_vector_highlighter
|
206
208
|
}
|
207
209
|
}
|
208
210
|
if autocomplete.include?(field)
|
data/lib/searchkick/results.rb
CHANGED
@@ -9,6 +9,16 @@ module Searchkick
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
+
def with_details
|
13
|
+
each_with_hit.map do |model, hit|
|
14
|
+
details = {}
|
15
|
+
if hit["highlight"]
|
16
|
+
details[:highlight] = Hash[ hit["highlight"].map{|k, v| [k.sub(/\.analyzed\z/, "").to_sym, v.first] } ]
|
17
|
+
end
|
18
|
+
[model, details]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
12
22
|
# fixes deprecation warning
|
13
23
|
def __find_records_by_ids(klass, ids)
|
14
24
|
@options[:load] === true ? klass.find(ids) : klass.includes(@options[:load][:include]).find(ids)
|
data/lib/searchkick/search.rb
CHANGED
@@ -70,9 +70,10 @@ module Searchkick
|
|
70
70
|
{multi_match: shared_options.merge(boost: 10, analyzer: "searchkick_search2")}
|
71
71
|
]
|
72
72
|
if options[:misspellings] != false
|
73
|
+
distance = (options[:misspellings].is_a?(Hash) && options[:misspellings][:distance]) || 1
|
73
74
|
queries.concat [
|
74
|
-
{multi_match: shared_options.merge(fuzziness:
|
75
|
-
{multi_match: shared_options.merge(fuzziness:
|
75
|
+
{multi_match: shared_options.merge(fuzziness: distance, max_expansions: 3, analyzer: "searchkick_search")},
|
76
|
+
{multi_match: shared_options.merge(fuzziness: distance, max_expansions: 3, analyzer: "searchkick_search2")}
|
76
77
|
]
|
77
78
|
end
|
78
79
|
payload = {
|
@@ -288,6 +289,17 @@ module Searchkick
|
|
288
289
|
end
|
289
290
|
end
|
290
291
|
|
292
|
+
# highlight
|
293
|
+
if options[:highlight]
|
294
|
+
payload[:highlight] = {
|
295
|
+
fields: Hash[ fields.map{|f| [f, {}] } ]
|
296
|
+
}
|
297
|
+
if options[:highlight].is_a?(Hash) and tag = options[:highlight][:tag]
|
298
|
+
payload[:highlight][:pre_tags] = [tag]
|
299
|
+
payload[:highlight][:post_tags] = [tag.to_s.gsub(/\A</, "</")]
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
291
303
|
# An empty array will cause only the _id and _type for each hit to be returned
|
292
304
|
# http://www.elasticsearch.org/guide/reference/api/search/fields/
|
293
305
|
payload[:fields] = [] if load
|
data/lib/searchkick/tasks.rb
CHANGED
@@ -23,8 +23,10 @@ namespace :searchkick do
|
|
23
23
|
task :all => :environment do
|
24
24
|
Rails.application.eager_load!
|
25
25
|
(Searchkick::Reindex.instance_variable_get(:@descendents) || []).each do |model|
|
26
|
+
puts "Reindexing #{model.name}..."
|
26
27
|
model.reindex
|
27
28
|
end
|
29
|
+
puts "Reindex complete"
|
28
30
|
end
|
29
31
|
end
|
30
32
|
|
data/lib/searchkick/version.rb
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
require_relative "test_helper"
|
2
|
+
|
3
|
+
class TestHighlight < Minitest::Unit::TestCase
|
4
|
+
|
5
|
+
def test_basic
|
6
|
+
store_names ["Two Door Cinema Club"]
|
7
|
+
assert_equal "Two Door <em>Cinema</em> Club", Product.search("cinema", fields: [:name], highlight: true).with_details.first[1][:highlight][:name]
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_tag
|
11
|
+
store_names ["Two Door Cinema Club"]
|
12
|
+
assert_equal "Two Door <strong>Cinema</strong> Club", Product.search("cinema", fields: [:name], highlight: {tag: "<strong>"}).with_details.first[1][:highlight][:name]
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_multiple_fields
|
16
|
+
store [{name: "Two Door Cinema Club", color: "Cinema Orange"}]
|
17
|
+
highlight = Product.search("cinema", fields: [:name, :color], highlight: true).with_details.first[1][:highlight]
|
18
|
+
assert_equal "Two Door <em>Cinema</em> Club", highlight[:name]
|
19
|
+
assert_equal "<em>Cinema</em> Orange", highlight[:color]
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
data/test/sql_test.rb
CHANGED
@@ -129,6 +129,11 @@ class TestSql < Minitest::Unit::TestCase
|
|
129
129
|
assert_search "abc", ["abc"], misspellings: false
|
130
130
|
end
|
131
131
|
|
132
|
+
def test_misspellings_distance
|
133
|
+
store_names ["abbb", "aabb"]
|
134
|
+
assert_search "aaaa", ["aabb"], misspellings: {distance: 2}
|
135
|
+
end
|
136
|
+
|
132
137
|
def test_fields
|
133
138
|
store [
|
134
139
|
{name: "red", color: "light blue"},
|
@@ -150,6 +155,13 @@ class TestSql < Minitest::Unit::TestCase
|
|
150
155
|
assert_first "blue", "Blue B", fields: [:name, :color]
|
151
156
|
end
|
152
157
|
|
158
|
+
def test_big_decimal
|
159
|
+
store [
|
160
|
+
{name: "Product", latitude: 100.0}
|
161
|
+
]
|
162
|
+
assert_search "product", ["Product"], where: {latitude: {gt: 99}}
|
163
|
+
end
|
164
|
+
|
153
165
|
# load
|
154
166
|
|
155
167
|
def test_load_default
|
data/test/suggest_test.rb
CHANGED
@@ -4,17 +4,17 @@ class TestSuggest < Minitest::Unit::TestCase
|
|
4
4
|
|
5
5
|
def test_basic
|
6
6
|
store_names ["Great White Shark", "Hammerhead Shark", "Tiger Shark"]
|
7
|
-
assert_suggest "How Big is a Tigre Shar", "how big is a tiger shark"
|
7
|
+
assert_suggest "How Big is a Tigre Shar", "how big is a tiger shark", fields: [:name]
|
8
8
|
end
|
9
9
|
|
10
10
|
def test_perfect
|
11
11
|
store_names ["Tiger Shark", "Great White Shark"]
|
12
|
-
assert_suggest "Tiger Shark", nil # no correction
|
12
|
+
assert_suggest "Tiger Shark", nil, fields: [:name] # no correction
|
13
13
|
end
|
14
14
|
|
15
15
|
def test_phrase
|
16
16
|
store_names ["Big Tiger Shark", "Tiger Sharp Teeth", "Tiger Sharp Mind"]
|
17
|
-
assert_suggest "How to catch a big tiger shar", "how to catch a big tiger shark"
|
17
|
+
assert_suggest "How to catch a big tiger shar", "how to catch a big tiger shark", fields: [:name]
|
18
18
|
end
|
19
19
|
|
20
20
|
def test_without_option
|
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.3.
|
4
|
+
version: 0.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-11-
|
11
|
+
date: 2013-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: tire
|
@@ -135,6 +135,7 @@ files:
|
|
135
135
|
- test/autocomplete_test.rb
|
136
136
|
- test/boost_test.rb
|
137
137
|
- test/facets_test.rb
|
138
|
+
- test/highlight_test.rb
|
138
139
|
- test/index_test.rb
|
139
140
|
- test/inheritance_test.rb
|
140
141
|
- test/match_test.rb
|
@@ -171,6 +172,7 @@ test_files:
|
|
171
172
|
- test/autocomplete_test.rb
|
172
173
|
- test/boost_test.rb
|
173
174
|
- test/facets_test.rb
|
175
|
+
- test/highlight_test.rb
|
174
176
|
- test/index_test.rb
|
175
177
|
- test/inheritance_test.rb
|
176
178
|
- test/match_test.rb
|