Commit 56b7cd3b836ef5dbe5db2f0cadce88afee149a38
1 parent
6f9fb3c5
Exists in
master
and in
21 other branches
Added basic support for multiple models - #38
Showing
5 changed files
with
43 additions
and
7 deletions
Show diff stats
CHANGELOG.md
@@ -4,6 +4,7 @@ | @@ -4,6 +4,7 @@ | ||
4 | - Added `analyzed_only` option for large text fields | 4 | - Added `analyzed_only` option for large text fields |
5 | - Added `encoder` option to highlight | 5 | - Added `encoder` option to highlight |
6 | - Fixed issue in `similar` method with `per_page` option | 6 | - Fixed issue in `similar` method with `per_page` option |
7 | +- Added basic support for multiple models | ||
7 | 8 | ||
8 | ## 1.1.2 | 9 | ## 1.1.2 |
9 | 10 |
README.md
@@ -1246,6 +1246,12 @@ class Product < ActiveRecord::Base | @@ -1246,6 +1246,12 @@ class Product < ActiveRecord::Base | ||
1246 | end | 1246 | end |
1247 | ``` | 1247 | ``` |
1248 | 1248 | ||
1249 | +Search multiple models [master] | ||
1250 | + | ||
1251 | +```ruby | ||
1252 | +Searchkick.search "milk", index_name: [Product, Category] | ||
1253 | +``` | ||
1254 | + | ||
1249 | Reindex all models - Rails only | 1255 | Reindex all models - Rails only |
1250 | 1256 | ||
1251 | ```sh | 1257 | ```sh |
lib/searchkick.rb
@@ -128,6 +128,16 @@ module Searchkick | @@ -128,6 +128,16 @@ module Searchkick | ||
128 | def self.callbacks_value=(value) | 128 | def self.callbacks_value=(value) |
129 | Thread.current[:searchkick_callbacks_enabled] = value | 129 | Thread.current[:searchkick_callbacks_enabled] = value |
130 | end | 130 | end |
131 | + | ||
132 | + def self.search(term = nil, options = {}, &block) | ||
133 | + query = Searchkick::Query.new(nil, term, options) | ||
134 | + block.call(query.body) if block | ||
135 | + if options[:execute] == false | ||
136 | + query | ||
137 | + else | ||
138 | + query.execute | ||
139 | + end | ||
140 | + end | ||
131 | end | 141 | end |
132 | 142 | ||
133 | # TODO find better ActiveModel hook | 143 | # TODO find better ActiveModel hook |
lib/searchkick/query.rb
@@ -28,20 +28,29 @@ module Searchkick | @@ -28,20 +28,29 @@ module Searchkick | ||
28 | end | 28 | end |
29 | 29 | ||
30 | def searchkick_index | 30 | def searchkick_index |
31 | - klass.searchkick_index | 31 | + klass ? klass.searchkick_index : nil |
32 | end | 32 | end |
33 | 33 | ||
34 | def searchkick_options | 34 | def searchkick_options |
35 | - klass.searchkick_options | 35 | + klass ? klass.searchkick_options : {} |
36 | end | 36 | end |
37 | 37 | ||
38 | def searchkick_klass | 38 | def searchkick_klass |
39 | - klass.searchkick_klass | 39 | + klass ? klass.searchkick_klass : nil |
40 | end | 40 | end |
41 | 41 | ||
42 | def params | 42 | def params |
43 | + index = | ||
44 | + if options[:index_name] | ||
45 | + Array(options[:index_name]).map { |v| v.respond_to?(:searchkick_index) ? v.searchkick_index.name : v }.join(",") | ||
46 | + elsif searchkick_index | ||
47 | + searchkick_index.name | ||
48 | + else | ||
49 | + "_all" | ||
50 | + end | ||
51 | + | ||
43 | params = { | 52 | params = { |
44 | - index: options[:index_name] || searchkick_index.name, | 53 | + index: index, |
45 | body: body | 54 | body: body |
46 | } | 55 | } |
47 | params.merge!(type: @type) if @type | 56 | params.merge!(type: @type) if @type |
@@ -60,7 +69,7 @@ module Searchkick | @@ -60,7 +69,7 @@ module Searchkick | ||
60 | rescue => e # TODO rescue type | 69 | rescue => e # TODO rescue type |
61 | status_code = e.message[1..3].to_i | 70 | status_code = e.message[1..3].to_i |
62 | if status_code == 404 | 71 | if status_code == 404 |
63 | - raise MissingIndexError, "Index missing - run #{searchkick_klass.name}.reindex" | 72 | + raise MissingIndexError, "Index missing - run #{reindex_command}" |
64 | elsif status_code == 500 && ( | 73 | elsif status_code == 500 && ( |
65 | e.message.include?("IllegalArgumentException[minimumSimilarity >= 1]") || | 74 | e.message.include?("IllegalArgumentException[minimumSimilarity >= 1]") || |
66 | e.message.include?("No query registered for [multi_match]") || | 75 | e.message.include?("No query registered for [multi_match]") || |
@@ -71,7 +80,7 @@ module Searchkick | @@ -71,7 +80,7 @@ module Searchkick | ||
71 | raise UnsupportedVersionError, "This version of Searchkick requires Elasticsearch 1.0 or greater" | 80 | raise UnsupportedVersionError, "This version of Searchkick requires Elasticsearch 1.0 or greater" |
72 | elsif status_code == 400 | 81 | elsif status_code == 400 |
73 | if e.message.include?("[multi_match] analyzer [searchkick_search] not found") | 82 | if e.message.include?("[multi_match] analyzer [searchkick_search] not found") |
74 | - raise InvalidQueryError, "Bad mapping - run #{searchkick_klass.name}.reindex" | 83 | + raise InvalidQueryError, "Bad mapping - run #{reindex_command}" |
75 | else | 84 | else |
76 | raise InvalidQueryError, e.message | 85 | raise InvalidQueryError, e.message |
77 | end | 86 | end |
@@ -116,6 +125,10 @@ module Searchkick | @@ -116,6 +125,10 @@ module Searchkick | ||
116 | 125 | ||
117 | private | 126 | private |
118 | 127 | ||
128 | + def reindex_command | ||
129 | + searchkick_klass ? "#{searchkick_klass.name}.reindex" : "reindex" | ||
130 | + end | ||
131 | + | ||
119 | def execute_search | 132 | def execute_search |
120 | Searchkick.client.search(params) | 133 | Searchkick.client.search(params) |
121 | end | 134 | end |
@@ -561,7 +574,7 @@ module Searchkick | @@ -561,7 +574,7 @@ module Searchkick | ||
561 | payload[:fields] = [] | 574 | payload[:fields] = [] |
562 | end | 575 | end |
563 | 576 | ||
564 | - if options[:type] || klass != searchkick_klass | 577 | + if options[:type] || (klass != searchkick_klass && searchkick_index) |
565 | @type = [options[:type] || klass].flatten.map { |v| searchkick_index.klass_document_type(v) } | 578 | @type = [options[:type] || klass].flatten.map { |v| searchkick_index.klass_document_type(v) } |
566 | end | 579 | end |
567 | 580 |
test/model_test.rb
@@ -33,4 +33,10 @@ class ModelTest < Minitest::Test | @@ -33,4 +33,10 @@ class ModelTest < Minitest::Test | ||
33 | 33 | ||
34 | assert_search "product", ["product a", "product b"] | 34 | assert_search "product", ["product a", "product b"] |
35 | end | 35 | end |
36 | + | ||
37 | + def test_multiple_models | ||
38 | + store_names ["Product A"] | ||
39 | + store_names ["Product B"], Store | ||
40 | + assert_equal Product.all + Store.all, Searchkick.search("product", index_name: [Product, Store], order: "name").to_a | ||
41 | + end | ||
36 | end | 42 | end |