Commit 56b7cd3b836ef5dbe5db2f0cadce88afee149a38

Authored by Andrew Kane
1 parent 6f9fb3c5

Added basic support for multiple models - #38

@@ -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
@@ -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