Commit 61ede188042c843c1dfd15fc724379ce69353887

Authored by Andrew
1 parent 3eac9fd5

Added inheritance option

1 ## 2.3.3 [unreleased] 1 ## 2.3.3 [unreleased]
2 2
3 - Fixed `similar` for Elasticsearch 6 3 - Fixed `similar` for Elasticsearch 6
  4 +- Added `inheritance` option
4 - Added `_type` option 5 - Added `_type` option
5 - Fixed `Must specify fields to search` error when searching `*` 6 - Fixed `Must specify fields to search` error when searching `*`
6 7
lib/searchkick/index.rb
@@ -318,12 +318,14 @@ module Searchkick @@ -318,12 +318,14 @@ module Searchkick
318 client.indices.analyze(body: {text: text}.merge(options), index: name)["tokens"].map { |t| t["token"] } 318 client.indices.analyze(body: {text: text}.merge(options), index: name)["tokens"].map { |t| t["token"] }
319 end 319 end
320 320
321 - def klass_document_type(klass)  
322 - @klass_document_type[klass] ||= begin 321 + def klass_document_type(klass, inheritance = true)
  322 + @klass_document_type[[klass, inheritance]] ||= begin
323 if klass.respond_to?(:document_type) 323 if klass.respond_to?(:document_type)
324 klass.document_type 324 klass.document_type
325 - elsif klass.searchkick_klass.searchkick_options[:_type]  
326 - klass.searchkick_klass.searchkick_options[:_type] 325 + elsif !inheritance && klass.searchkick_klass.searchkick_options[:_type]
  326 + type = klass.searchkick_klass.searchkick_options[:_type]
  327 + type = type.call if type.respond_to?(:call)
  328 + type
327 else 329 else
328 klass.model_name.to_s.underscore 330 klass.model_name.to_s.underscore
329 end 331 end
@@ -336,11 +338,11 @@ module Searchkick @@ -336,11 +338,11 @@ module Searchkick
336 Searchkick.client 338 Searchkick.client
337 end 339 end
338 340
339 - def document_type(record) 341 + def document_type(record, inheritance = false)
340 if record.respond_to?(:search_document_type) 342 if record.respond_to?(:search_document_type)
341 record.search_document_type 343 record.search_document_type
342 else 344 else
343 - klass_document_type(record.class) 345 + klass_document_type(record.class, inheritance)
344 end 346 end
345 end 347 end
346 348
@@ -388,6 +390,10 @@ module Searchkick @@ -388,6 +390,10 @@ module Searchkick
388 end 390 end
389 end 391 end
390 392
  393 + if !source.key?("type") && record.class.searchkick_klass.searchkick_options[:inheritance]
  394 + source["type"] = document_type(record, true)
  395 + end
  396 +
391 cast_big_decimal(source) 397 cast_big_decimal(source)
392 398
393 source 399 source
lib/searchkick/index_options.rb
@@ -277,6 +277,10 @@ module Searchkick @@ -277,6 +277,10 @@ module Searchkick
277 mapping[field] = shape_options.merge(type: "geo_shape") 277 mapping[field] = shape_options.merge(type: "geo_shape")
278 end 278 end
279 279
  280 + if options[:inheritance]
  281 + mapping[:type] = keyword_mapping
  282 + end
  283 +
280 routing = {} 284 routing = {}
281 if options[:routing] 285 if options[:routing]
282 routing = {required: true} 286 routing = {required: true}
lib/searchkick/model.rb
@@ -2,7 +2,7 @@ module Searchkick @@ -2,7 +2,7 @@ module Searchkick
2 module Model 2 module Model
3 def searchkick(**options) 3 def searchkick(**options)
4 unknown_keywords = options.keys - [:_all, :_type, :batch_size, :callbacks, :conversions, :default_fields, 4 unknown_keywords = options.keys - [:_all, :_type, :batch_size, :callbacks, :conversions, :default_fields,
5 - :filterable, :geo_shape, :highlight, :ignore_above, :index_name, :index_prefix, :language, 5 + :filterable, :geo_shape, :highlight, :ignore_above, :index_name, :index_prefix, :inheritance, :language,
6 :locations, :mappings, :match, :merge_mappings, :routing, :searchable, :settings, :similarity, 6 :locations, :mappings, :match, :merge_mappings, :routing, :searchable, :settings, :similarity,
7 :special_characters, :stem_conversions, :suggest, :synonyms, :text_end, 7 :special_characters, :stem_conversions, :suggest, :synonyms, :text_end,
8 :text_middle, :text_start, :word, :wordnet, :word_end, :word_middle, :word_start] 8 :text_middle, :text_start, :word, :wordnet, :word_end, :word_middle, :word_start]
@@ -12,6 +12,8 @@ module Searchkick @@ -12,6 +12,8 @@ module Searchkick
12 12
13 Searchkick.models << self 13 Searchkick.models << self
14 14
  15 + options[:_type] ||= -> { searchkick_index.klass_document_type(self) } if options[:inheritance]
  16 +
15 class_eval do 17 class_eval do
16 cattr_reader :searchkick_options, :searchkick_klass 18 cattr_reader :searchkick_options, :searchkick_klass
17 19
lib/searchkick/query.rb
@@ -449,8 +449,14 @@ module Searchkick @@ -449,8 +449,14 @@ module Searchkick
449 # indices_boost 449 # indices_boost
450 set_boost_by_indices(payload) 450 set_boost_by_indices(payload)
451 451
  452 + # type when inheritance
  453 + where = (options[:where] || {}).dup
  454 + if searchkick_options[:inheritance] && (options[:type] || (klass != searchkick_klass && searchkick_index))
  455 + where[:type] = [options[:type] || klass].flatten.map { |v| searchkick_index.klass_document_type(v) }
  456 + end
  457 +
452 # filters 458 # filters
453 - filters = where_filters(options[:where]) 459 + filters = where_filters(where)
454 set_filters(payload, filters) if filters.any? 460 set_filters(payload, filters) if filters.any?
455 461
456 # aggregations 462 # aggregations
@@ -480,7 +486,7 @@ module Searchkick @@ -480,7 +486,7 @@ module Searchkick
480 end 486 end
481 487
482 # type 488 # type
483 - if options[:type] || (klass != searchkick_klass && searchkick_index) 489 + if !searchkick_options[:inheritance] && (options[:type] || (klass != searchkick_klass && searchkick_index))
484 @type = [options[:type] || klass].flatten.map { |v| searchkick_index.klass_document_type(v) } 490 @type = [options[:type] || klass].flatten.map { |v| searchkick_index.klass_document_type(v) }
485 end 491 end
486 492
test/inheritance_test.rb
@@ -17,8 +17,6 @@ class InheritanceTest &lt; Minitest::Test @@ -17,8 +17,6 @@ class InheritanceTest &lt; Minitest::Test
17 end 17 end
18 18
19 def test_child_search 19 def test_child_search
20 - skip unless elasticsearch_below60?  
21 -  
22 store_names ["Bear"], Dog 20 store_names ["Bear"], Dog
23 store_names ["Bear"], Cat 21 store_names ["Bear"], Cat
24 assert_equal 1, Dog.search("bear").size 22 assert_equal 1, Dog.search("bear").size
@@ -31,16 +29,12 @@ class InheritanceTest &lt; Minitest::Test @@ -31,16 +29,12 @@ class InheritanceTest &lt; Minitest::Test
31 end 29 end
32 30
33 def test_force_one_type 31 def test_force_one_type
34 - skip unless elasticsearch_below60?  
35 -  
36 store_names ["Green Bear"], Dog 32 store_names ["Green Bear"], Dog
37 store_names ["Blue Bear"], Cat 33 store_names ["Blue Bear"], Cat
38 assert_equal ["Blue Bear"], Animal.search("bear", type: [Cat]).map(&:name) 34 assert_equal ["Blue Bear"], Animal.search("bear", type: [Cat]).map(&:name)
39 end 35 end
40 36
41 def test_force_multiple_types 37 def test_force_multiple_types
42 - skip unless elasticsearch_below60?  
43 -  
44 store_names ["Green Bear"], Dog 38 store_names ["Green Bear"], Dog
45 store_names ["Blue Bear"], Cat 39 store_names ["Blue Bear"], Cat
46 store_names ["Red Bear"], Animal 40 store_names ["Red Bear"], Animal
@@ -48,8 +42,6 @@ class InheritanceTest &lt; Minitest::Test @@ -48,8 +42,6 @@ class InheritanceTest &lt; Minitest::Test
48 end 42 end
49 43
50 def test_child_autocomplete 44 def test_child_autocomplete
51 - skip unless elasticsearch_below60?  
52 -  
53 store_names ["Max"], Cat 45 store_names ["Max"], Cat
54 store_names ["Mark"], Dog 46 store_names ["Mark"], Dog
55 assert_equal ["Max"], Cat.search("ma", fields: [:name], match: :text_start).map(&:name) 47 assert_equal ["Max"], Cat.search("ma", fields: [:name], match: :text_start).map(&:name)
test/test_helper.rb
@@ -505,7 +505,7 @@ end @@ -505,7 +505,7 @@ end
505 class Animal 505 class Animal
506 searchkick \ 506 searchkick \
507 default_fields: elasticsearch_below60? ? nil : [:name], 507 default_fields: elasticsearch_below60? ? nil : [:name],
508 - _type: elasticsearch_below60? ? nil : :animal, 508 + inheritance: !elasticsearch_below60?,
509 text_start: [:name], 509 text_start: [:name],
510 suggest: [:name], 510 suggest: [:name],
511 index_name: -> { "#{name.tableize}-#{Date.today.year}#{Searchkick.index_suffix}" }, 511 index_name: -> { "#{name.tableize}-#{Date.today.year}#{Searchkick.index_suffix}" },