Commit 56b7cd3b836ef5dbe5db2f0cadce88afee149a38

Authored by Andrew Kane
1 parent 6f9fb3c5

Added basic support for multiple models - #38

CHANGELOG.md
... ... @@ -4,6 +4,7 @@
4 4 - Added `analyzed_only` option for large text fields
5 5 - Added `encoder` option to highlight
6 6 - Fixed issue in `similar` method with `per_page` option
  7 +- Added basic support for multiple models
7 8  
8 9 ## 1.1.2
9 10  
... ...
README.md
... ... @@ -1246,6 +1246,12 @@ class Product < ActiveRecord::Base
1246 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 1255 Reindex all models - Rails only
1250 1256  
1251 1257 ```sh
... ...
lib/searchkick.rb
... ... @@ -128,6 +128,16 @@ module Searchkick
128 128 def self.callbacks_value=(value)
129 129 Thread.current[:searchkick_callbacks_enabled] = value
130 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 141 end
132 142  
133 143 # TODO find better ActiveModel hook
... ...
lib/searchkick/query.rb
... ... @@ -28,20 +28,29 @@ module Searchkick
28 28 end
29 29  
30 30 def searchkick_index
31   - klass.searchkick_index
  31 + klass ? klass.searchkick_index : nil
32 32 end
33 33  
34 34 def searchkick_options
35   - klass.searchkick_options
  35 + klass ? klass.searchkick_options : {}
36 36 end
37 37  
38 38 def searchkick_klass
39   - klass.searchkick_klass
  39 + klass ? klass.searchkick_klass : nil
40 40 end
41 41  
42 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 52 params = {
44   - index: options[:index_name] || searchkick_index.name,
  53 + index: index,
45 54 body: body
46 55 }
47 56 params.merge!(type: @type) if @type
... ... @@ -60,7 +69,7 @@ module Searchkick
60 69 rescue => e # TODO rescue type
61 70 status_code = e.message[1..3].to_i
62 71 if status_code == 404
63   - raise MissingIndexError, "Index missing - run #{searchkick_klass.name}.reindex"
  72 + raise MissingIndexError, "Index missing - run #{reindex_command}"
64 73 elsif status_code == 500 && (
65 74 e.message.include?("IllegalArgumentException[minimumSimilarity >= 1]") ||
66 75 e.message.include?("No query registered for [multi_match]") ||
... ... @@ -71,7 +80,7 @@ module Searchkick
71 80 raise UnsupportedVersionError, "This version of Searchkick requires Elasticsearch 1.0 or greater"
72 81 elsif status_code == 400
73 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 84 else
76 85 raise InvalidQueryError, e.message
77 86 end
... ... @@ -116,6 +125,10 @@ module Searchkick
116 125  
117 126 private
118 127  
  128 + def reindex_command
  129 + searchkick_klass ? "#{searchkick_klass.name}.reindex" : "reindex"
  130 + end
  131 +
119 132 def execute_search
120 133 Searchkick.client.search(params)
121 134 end
... ... @@ -561,7 +574,7 @@ module Searchkick
561 574 payload[:fields] = []
562 575 end
563 576  
564   - if options[:type] || klass != searchkick_klass
  577 + if options[:type] || (klass != searchkick_klass && searchkick_index)
565 578 @type = [options[:type] || klass].flatten.map { |v| searchkick_index.klass_document_type(v) }
566 579 end
567 580  
... ...
test/model_test.rb
... ... @@ -33,4 +33,10 @@ class ModelTest < Minitest::Test
33 33  
34 34 assert_search "product", ["product a", "product b"]
35 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 42 end
... ...