From 56b7cd3b836ef5dbe5db2f0cadce88afee149a38 Mon Sep 17 00:00:00 2001 From: Andrew Kane Date: Tue, 2 Feb 2016 21:45:42 -0800 Subject: [PATCH] Added basic support for multiple models - #38 --- CHANGELOG.md | 1 + README.md | 6 ++++++ lib/searchkick.rb | 10 ++++++++++ lib/searchkick/query.rb | 27 ++++++++++++++++++++------- test/model_test.rb | 6 ++++++ 5 files changed, 43 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e3121e..5f79c62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Added `analyzed_only` option for large text fields - Added `encoder` option to highlight - Fixed issue in `similar` method with `per_page` option +- Added basic support for multiple models ## 1.1.2 diff --git a/README.md b/README.md index 3526d34..e671b5d 100644 --- a/README.md +++ b/README.md @@ -1246,6 +1246,12 @@ class Product < ActiveRecord::Base end ``` +Search multiple models [master] + +```ruby +Searchkick.search "milk", index_name: [Product, Category] +``` + Reindex all models - Rails only ```sh diff --git a/lib/searchkick.rb b/lib/searchkick.rb index 2fd4c64..5f63da8 100644 --- a/lib/searchkick.rb +++ b/lib/searchkick.rb @@ -128,6 +128,16 @@ module Searchkick def self.callbacks_value=(value) Thread.current[:searchkick_callbacks_enabled] = value end + + def self.search(term = nil, options = {}, &block) + query = Searchkick::Query.new(nil, term, options) + block.call(query.body) if block + if options[:execute] == false + query + else + query.execute + end + end end # TODO find better ActiveModel hook diff --git a/lib/searchkick/query.rb b/lib/searchkick/query.rb index e5ef44a..fbbdf63 100644 --- a/lib/searchkick/query.rb +++ b/lib/searchkick/query.rb @@ -28,20 +28,29 @@ module Searchkick end def searchkick_index - klass.searchkick_index + klass ? klass.searchkick_index : nil end def searchkick_options - klass.searchkick_options + klass ? klass.searchkick_options : {} end def searchkick_klass - klass.searchkick_klass + klass ? klass.searchkick_klass : nil end def params + index = + if options[:index_name] + Array(options[:index_name]).map { |v| v.respond_to?(:searchkick_index) ? v.searchkick_index.name : v }.join(",") + elsif searchkick_index + searchkick_index.name + else + "_all" + end + params = { - index: options[:index_name] || searchkick_index.name, + index: index, body: body } params.merge!(type: @type) if @type @@ -60,7 +69,7 @@ module Searchkick rescue => e # TODO rescue type status_code = e.message[1..3].to_i if status_code == 404 - raise MissingIndexError, "Index missing - run #{searchkick_klass.name}.reindex" + raise MissingIndexError, "Index missing - run #{reindex_command}" elsif status_code == 500 && ( e.message.include?("IllegalArgumentException[minimumSimilarity >= 1]") || e.message.include?("No query registered for [multi_match]") || @@ -71,7 +80,7 @@ module Searchkick raise UnsupportedVersionError, "This version of Searchkick requires Elasticsearch 1.0 or greater" elsif status_code == 400 if e.message.include?("[multi_match] analyzer [searchkick_search] not found") - raise InvalidQueryError, "Bad mapping - run #{searchkick_klass.name}.reindex" + raise InvalidQueryError, "Bad mapping - run #{reindex_command}" else raise InvalidQueryError, e.message end @@ -116,6 +125,10 @@ module Searchkick private + def reindex_command + searchkick_klass ? "#{searchkick_klass.name}.reindex" : "reindex" + end + def execute_search Searchkick.client.search(params) end @@ -561,7 +574,7 @@ module Searchkick payload[:fields] = [] end - if options[:type] || klass != searchkick_klass + if options[:type] || (klass != searchkick_klass && searchkick_index) @type = [options[:type] || klass].flatten.map { |v| searchkick_index.klass_document_type(v) } end diff --git a/test/model_test.rb b/test/model_test.rb index c7080c3..9f5236a 100644 --- a/test/model_test.rb +++ b/test/model_test.rb @@ -33,4 +33,10 @@ class ModelTest < Minitest::Test assert_search "product", ["product a", "product b"] end + + def test_multiple_models + store_names ["Product A"] + store_names ["Product B"], Store + assert_equal Product.all + Store.all, Searchkick.search("product", index_name: [Product, Store], order: "name").to_a + end end -- libgit2 0.21.0