Commit 61ede188042c843c1dfd15fc724379ce69353887

Authored by Andrew
1 parent 3eac9fd5

Added inheritance option

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