Commit 7e6d2bc7cab9c2a62ee4e5f99a02887f607dbc1e
1 parent
55cfb407
Exists in
master
and in
21 other branches
Added search for similar items
Showing
6 changed files
with
57 additions
and
1 deletions
Show diff stats
README.md
... | ... | @@ -284,6 +284,17 @@ Advanced |
284 | 284 | Product.search "2% Milk", facets: {store_id: {where: {in_stock: true}}} |
285 | 285 | ``` |
286 | 286 | |
287 | +### Similar Items [master] | |
288 | + | |
289 | +**Note:** Subject to change before the next gem release | |
290 | + | |
291 | +Find similar items. | |
292 | + | |
293 | +```ruby | |
294 | +product = Product.first | |
295 | +product.similar(fields: ["name"]) | |
296 | +``` | |
297 | + | |
287 | 298 | ## Deployment |
288 | 299 | |
289 | 300 | Searchkick uses `ENV["ELASTICSEARCH_URL"]` for the Elasticsearch server. This defaults to `http://localhost:9200`. | ... | ... |
lib/searchkick.rb
... | ... | @@ -3,6 +3,7 @@ require "searchkick/version" |
3 | 3 | require "searchkick/reindex" |
4 | 4 | require "searchkick/results" |
5 | 5 | require "searchkick/search" |
6 | +require "searchkick/similar" | |
6 | 7 | require "searchkick/model" |
7 | 8 | require "searchkick/tasks" |
8 | 9 | require "searchkick/logger" if defined?(Rails) | ... | ... |
lib/searchkick/model.rb
... | ... | @@ -0,0 +1,32 @@ |
1 | +module Searchkick | |
2 | + module Similar | |
3 | + def similar(options = {}) | |
4 | + like_text = index.retrieve(document_type, id).to_hash | |
5 | + .keep_if{|k,v| k[0] != "_" and (!options[:fields] or options[:fields].map(&:to_sym).include?(k)) } | |
6 | + .values.compact.join(" ") | |
7 | + | |
8 | + fields = options[:fields] ? options[:fields].map{|f| "#{f}.analyzed" } : ["_all"] | |
9 | + | |
10 | + payload = { | |
11 | + query: { | |
12 | + more_like_this: { | |
13 | + fields: fields, | |
14 | + like_text: like_text, | |
15 | + min_doc_freq: 1, | |
16 | + min_term_freq: 1 | |
17 | + } | |
18 | + }, | |
19 | + filter: { | |
20 | + not: { | |
21 | + term: { | |
22 | + _id: id | |
23 | + } | |
24 | + } | |
25 | + } | |
26 | + } | |
27 | + | |
28 | + search = Tire::Search::Search.new(index_name, payload: payload) | |
29 | + Searchkick::Results.new(search.json, search.options) | |
30 | + end | |
31 | + end | |
32 | +end | ... | ... |
... | ... | @@ -0,0 +1,10 @@ |
1 | +require_relative "test_helper" | |
2 | + | |
3 | +class TestSimilar < Minitest::Unit::TestCase | |
4 | + | |
5 | + def test_fields | |
6 | + store_names ["1% Organic Milk", "2% Organic Milk", "Popcorn"] | |
7 | + assert_equal ["2% Organic Milk"], Product.find_by(name: "1% Organic Milk").similar(fields: ["name"]).map(&:name) | |
8 | + end | |
9 | + | |
10 | +end | ... | ... |
test/test_helper.rb