diff --git a/CHANGELOG.md b/CHANGELOG.md index 618e49d..59df474 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## 2.3.3 [unreleased] - Fixed `similar` for Elasticsearch 6 +- Added `inheritance` option - Added `_type` option - Fixed `Must specify fields to search` error when searching `*` diff --git a/lib/searchkick/index.rb b/lib/searchkick/index.rb index 6f29b7a..429ea68 100644 --- a/lib/searchkick/index.rb +++ b/lib/searchkick/index.rb @@ -318,12 +318,14 @@ module Searchkick client.indices.analyze(body: {text: text}.merge(options), index: name)["tokens"].map { |t| t["token"] } end - def klass_document_type(klass) - @klass_document_type[klass] ||= begin + def klass_document_type(klass, inheritance = true) + @klass_document_type[[klass, inheritance]] ||= begin if klass.respond_to?(:document_type) klass.document_type - elsif klass.searchkick_klass.searchkick_options[:_type] - klass.searchkick_klass.searchkick_options[:_type] + elsif !inheritance && klass.searchkick_klass.searchkick_options[:_type] + type = klass.searchkick_klass.searchkick_options[:_type] + type = type.call if type.respond_to?(:call) + type else klass.model_name.to_s.underscore end @@ -336,11 +338,11 @@ module Searchkick Searchkick.client end - def document_type(record) + def document_type(record, inheritance = false) if record.respond_to?(:search_document_type) record.search_document_type else - klass_document_type(record.class) + klass_document_type(record.class, inheritance) end end @@ -388,6 +390,10 @@ module Searchkick end end + if !source.key?("type") && record.class.searchkick_klass.searchkick_options[:inheritance] + source["type"] = document_type(record, true) + end + cast_big_decimal(source) source diff --git a/lib/searchkick/index_options.rb b/lib/searchkick/index_options.rb index d9d4211..225cbdc 100644 --- a/lib/searchkick/index_options.rb +++ b/lib/searchkick/index_options.rb @@ -277,6 +277,10 @@ module Searchkick mapping[field] = shape_options.merge(type: "geo_shape") end + if options[:inheritance] + mapping[:type] = keyword_mapping + end + routing = {} if options[:routing] routing = {required: true} diff --git a/lib/searchkick/model.rb b/lib/searchkick/model.rb index f0aeaec..e10e700 100644 --- a/lib/searchkick/model.rb +++ b/lib/searchkick/model.rb @@ -2,7 +2,7 @@ module Searchkick module Model def searchkick(**options) unknown_keywords = options.keys - [:_all, :_type, :batch_size, :callbacks, :conversions, :default_fields, - :filterable, :geo_shape, :highlight, :ignore_above, :index_name, :index_prefix, :language, + :filterable, :geo_shape, :highlight, :ignore_above, :index_name, :index_prefix, :inheritance, :language, :locations, :mappings, :match, :merge_mappings, :routing, :searchable, :settings, :similarity, :special_characters, :stem_conversions, :suggest, :synonyms, :text_end, :text_middle, :text_start, :word, :wordnet, :word_end, :word_middle, :word_start] @@ -12,6 +12,8 @@ module Searchkick Searchkick.models << self + options[:_type] ||= -> { searchkick_index.klass_document_type(self) } if options[:inheritance] + class_eval do cattr_reader :searchkick_options, :searchkick_klass diff --git a/lib/searchkick/query.rb b/lib/searchkick/query.rb index 2920202..37e0b9d 100644 --- a/lib/searchkick/query.rb +++ b/lib/searchkick/query.rb @@ -449,8 +449,14 @@ module Searchkick # indices_boost set_boost_by_indices(payload) + # type when inheritance + where = (options[:where] || {}).dup + if searchkick_options[:inheritance] && (options[:type] || (klass != searchkick_klass && searchkick_index)) + where[:type] = [options[:type] || klass].flatten.map { |v| searchkick_index.klass_document_type(v) } + end + # filters - filters = where_filters(options[:where]) + filters = where_filters(where) set_filters(payload, filters) if filters.any? # aggregations @@ -480,7 +486,7 @@ module Searchkick end # type - if options[:type] || (klass != searchkick_klass && searchkick_index) + if !searchkick_options[:inheritance] && (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/inheritance_test.rb b/test/inheritance_test.rb index a7e0461..e42a6f7 100644 --- a/test/inheritance_test.rb +++ b/test/inheritance_test.rb @@ -17,8 +17,6 @@ class InheritanceTest < Minitest::Test end def test_child_search - skip unless elasticsearch_below60? - store_names ["Bear"], Dog store_names ["Bear"], Cat assert_equal 1, Dog.search("bear").size @@ -31,16 +29,12 @@ class InheritanceTest < Minitest::Test end def test_force_one_type - skip unless elasticsearch_below60? - store_names ["Green Bear"], Dog store_names ["Blue Bear"], Cat assert_equal ["Blue Bear"], Animal.search("bear", type: [Cat]).map(&:name) end def test_force_multiple_types - skip unless elasticsearch_below60? - store_names ["Green Bear"], Dog store_names ["Blue Bear"], Cat store_names ["Red Bear"], Animal @@ -48,8 +42,6 @@ class InheritanceTest < Minitest::Test end def test_child_autocomplete - skip unless elasticsearch_below60? - store_names ["Max"], Cat store_names ["Mark"], Dog assert_equal ["Max"], Cat.search("ma", fields: [:name], match: :text_start).map(&:name) diff --git a/test/test_helper.rb b/test/test_helper.rb index df4d653..1e4272d 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -505,7 +505,7 @@ end class Animal searchkick \ default_fields: elasticsearch_below60? ? nil : [:name], - _type: elasticsearch_below60? ? nil : :animal, + inheritance: !elasticsearch_below60?, text_start: [:name], suggest: [:name], index_name: -> { "#{name.tableize}-#{Date.today.year}#{Searchkick.index_suffix}" }, -- libgit2 0.21.0