Commit 54c48b92f0ef2d197369c03b6096bb3e19d6713e
1 parent
f915ef75
Exists in
master
and in
8 other branches
Added generate mappings method
Showing
1 changed file
with
135 additions
and
130 deletions
Show diff stats
lib/searchkick/index_options.rb
... | ... | @@ -23,138 +23,10 @@ module Searchkick |
23 | 23 | mappings = custom_mapping |
24 | 24 | else |
25 | 25 | settings = generate_settings |
26 | - | |
27 | - mapping = {} | |
28 | - | |
29 | - keyword_mapping = {type: "keyword"} | |
30 | - keyword_mapping[:ignore_above] = options[:ignore_above] || 30000 | |
31 | - | |
32 | - # conversions | |
33 | - Array(options[:conversions]).each do |conversions_field| | |
34 | - mapping[conversions_field] = { | |
35 | - type: "nested", | |
36 | - properties: { | |
37 | - query: {type: default_type, analyzer: "searchkick_keyword"}, | |
38 | - count: {type: "integer"} | |
39 | - } | |
40 | - } | |
41 | - end | |
42 | - | |
43 | - mapping_options = Hash[ | |
44 | - [:suggest, :word, :text_start, :text_middle, :text_end, :word_start, :word_middle, :word_end, :highlight, :searchable, :filterable] | |
45 | - .map { |type| [type, (options[type] || []).map(&:to_s)] } | |
46 | - ] | |
47 | - | |
48 | - word = options[:word] != false && (!options[:match] || options[:match] == :word) | |
49 | - | |
50 | - mapping_options[:searchable].delete("_all") | |
51 | - | |
52 | - analyzed_field_options = {type: default_type, index: true, analyzer: default_analyzer} | |
53 | - | |
54 | - mapping_options.values.flatten.uniq.each do |field| | |
55 | - fields = {} | |
56 | - | |
57 | - if options.key?(:filterable) && !mapping_options[:filterable].include?(field) | |
58 | - fields[field] = {type: default_type, index: false} | |
59 | - else | |
60 | - fields[field] = keyword_mapping | |
61 | - end | |
62 | - | |
63 | - if !options[:searchable] || mapping_options[:searchable].include?(field) | |
64 | - if word | |
65 | - fields[:analyzed] = analyzed_field_options | |
66 | - | |
67 | - if mapping_options[:highlight].include?(field) | |
68 | - fields[:analyzed][:term_vector] = "with_positions_offsets" | |
69 | - end | |
70 | - end | |
71 | - | |
72 | - mapping_options.except(:highlight, :searchable, :filterable, :word).each do |type, f| | |
73 | - if options[:match] == type || f.include?(field) | |
74 | - fields[type] = {type: default_type, index: true, analyzer: "searchkick_#{type}_index"} | |
75 | - end | |
76 | - end | |
77 | - end | |
78 | - | |
79 | - mapping[field] = fields[field].merge(fields: fields.except(field)) | |
80 | - end | |
81 | - | |
82 | - (options[:locations] || []).map(&:to_s).each do |field| | |
83 | - mapping[field] = { | |
84 | - type: "geo_point" | |
85 | - } | |
86 | - end | |
87 | - | |
88 | - options[:geo_shape] = options[:geo_shape].product([{}]).to_h if options[:geo_shape].is_a?(Array) | |
89 | - (options[:geo_shape] || {}).each do |field, shape_options| | |
90 | - mapping[field] = shape_options.merge(type: "geo_shape") | |
91 | - end | |
92 | - | |
93 | - if options[:inheritance] | |
94 | - mapping[:type] = keyword_mapping | |
95 | - end | |
96 | - | |
97 | - routing = {} | |
98 | - if options[:routing] | |
99 | - routing = {required: true} | |
100 | - unless options[:routing] == true | |
101 | - routing[:path] = options[:routing].to_s | |
102 | - end | |
103 | - end | |
104 | - | |
105 | - dynamic_fields = { | |
106 | - # analyzed field must be the default field for include_in_all | |
107 | - # http://www.elasticsearch.org/guide/reference/mapping/multi-field-type/ | |
108 | - # however, we can include the not_analyzed field in _all | |
109 | - # and the _all index analyzer will take care of it | |
110 | - "{name}" => keyword_mapping | |
111 | - } | |
112 | - | |
113 | - if options.key?(:filterable) | |
114 | - dynamic_fields["{name}"] = {type: default_type, index: false} | |
115 | - end | |
116 | - | |
117 | - unless options[:searchable] | |
118 | - if options[:match] && options[:match] != :word | |
119 | - dynamic_fields[options[:match]] = {type: default_type, index: true, analyzer: "searchkick_#{options[:match]}_index"} | |
120 | - end | |
121 | - | |
122 | - if word | |
123 | - dynamic_fields[:analyzed] = analyzed_field_options | |
124 | - end | |
125 | - end | |
126 | - | |
127 | - # http://www.elasticsearch.org/guide/reference/mapping/multi-field-type/ | |
128 | - multi_field = dynamic_fields["{name}"].merge(fields: dynamic_fields.except("{name}")) | |
129 | - | |
130 | - mappings = { | |
131 | - properties: mapping, | |
132 | - _routing: routing, | |
133 | - # https://gist.github.com/kimchy/2898285 | |
134 | - dynamic_templates: [ | |
135 | - { | |
136 | - string_template: { | |
137 | - match: "*", | |
138 | - match_mapping_type: "string", | |
139 | - mapping: multi_field | |
140 | - } | |
141 | - } | |
142 | - ] | |
143 | - } | |
144 | - | |
145 | - if below70 | |
146 | - mappings = {index_type => mappings} | |
147 | - end | |
148 | - | |
149 | - mappings = mappings.symbolize_keys.deep_merge(custom_mapping.symbolize_keys) | |
26 | + mappings = generate_mappings.symbolize_keys.deep_merge(custom_mapping.symbolize_keys) | |
150 | 27 | end |
151 | 28 | |
152 | - if options[:deep_paging] | |
153 | - if !settings.dig(:index, :max_result_window) && !settings[:"index.max_result_window"] | |
154 | - settings[:index] ||= {} | |
155 | - settings[:index][:max_result_window] = 1_000_000_000 | |
156 | - end | |
157 | - end | |
29 | + set_deep_paging(settings) if options[:deep_paging] | |
158 | 30 | |
159 | 31 | { |
160 | 32 | settings: settings, |
... | ... | @@ -433,6 +305,132 @@ module Searchkick |
433 | 305 | settings |
434 | 306 | end |
435 | 307 | |
308 | + def generate_mappings | |
309 | + mapping = {} | |
310 | + | |
311 | + keyword_mapping = {type: "keyword"} | |
312 | + keyword_mapping[:ignore_above] = options[:ignore_above] || 30000 | |
313 | + | |
314 | + # conversions | |
315 | + Array(options[:conversions]).each do |conversions_field| | |
316 | + mapping[conversions_field] = { | |
317 | + type: "nested", | |
318 | + properties: { | |
319 | + query: {type: default_type, analyzer: "searchkick_keyword"}, | |
320 | + count: {type: "integer"} | |
321 | + } | |
322 | + } | |
323 | + end | |
324 | + | |
325 | + mapping_options = Hash[ | |
326 | + [:suggest, :word, :text_start, :text_middle, :text_end, :word_start, :word_middle, :word_end, :highlight, :searchable, :filterable] | |
327 | + .map { |type| [type, (options[type] || []).map(&:to_s)] } | |
328 | + ] | |
329 | + | |
330 | + word = options[:word] != false && (!options[:match] || options[:match] == :word) | |
331 | + | |
332 | + mapping_options[:searchable].delete("_all") | |
333 | + | |
334 | + analyzed_field_options = {type: default_type, index: true, analyzer: default_analyzer} | |
335 | + | |
336 | + mapping_options.values.flatten.uniq.each do |field| | |
337 | + fields = {} | |
338 | + | |
339 | + if options.key?(:filterable) && !mapping_options[:filterable].include?(field) | |
340 | + fields[field] = {type: default_type, index: false} | |
341 | + else | |
342 | + fields[field] = keyword_mapping | |
343 | + end | |
344 | + | |
345 | + if !options[:searchable] || mapping_options[:searchable].include?(field) | |
346 | + if word | |
347 | + fields[:analyzed] = analyzed_field_options | |
348 | + | |
349 | + if mapping_options[:highlight].include?(field) | |
350 | + fields[:analyzed][:term_vector] = "with_positions_offsets" | |
351 | + end | |
352 | + end | |
353 | + | |
354 | + mapping_options.except(:highlight, :searchable, :filterable, :word).each do |type, f| | |
355 | + if options[:match] == type || f.include?(field) | |
356 | + fields[type] = {type: default_type, index: true, analyzer: "searchkick_#{type}_index"} | |
357 | + end | |
358 | + end | |
359 | + end | |
360 | + | |
361 | + mapping[field] = fields[field].merge(fields: fields.except(field)) | |
362 | + end | |
363 | + | |
364 | + (options[:locations] || []).map(&:to_s).each do |field| | |
365 | + mapping[field] = { | |
366 | + type: "geo_point" | |
367 | + } | |
368 | + end | |
369 | + | |
370 | + options[:geo_shape] = options[:geo_shape].product([{}]).to_h if options[:geo_shape].is_a?(Array) | |
371 | + (options[:geo_shape] || {}).each do |field, shape_options| | |
372 | + mapping[field] = shape_options.merge(type: "geo_shape") | |
373 | + end | |
374 | + | |
375 | + if options[:inheritance] | |
376 | + mapping[:type] = keyword_mapping | |
377 | + end | |
378 | + | |
379 | + routing = {} | |
380 | + if options[:routing] | |
381 | + routing = {required: true} | |
382 | + unless options[:routing] == true | |
383 | + routing[:path] = options[:routing].to_s | |
384 | + end | |
385 | + end | |
386 | + | |
387 | + dynamic_fields = { | |
388 | + # analyzed field must be the default field for include_in_all | |
389 | + # http://www.elasticsearch.org/guide/reference/mapping/multi-field-type/ | |
390 | + # however, we can include the not_analyzed field in _all | |
391 | + # and the _all index analyzer will take care of it | |
392 | + "{name}" => keyword_mapping | |
393 | + } | |
394 | + | |
395 | + if options.key?(:filterable) | |
396 | + dynamic_fields["{name}"] = {type: default_type, index: false} | |
397 | + end | |
398 | + | |
399 | + unless options[:searchable] | |
400 | + if options[:match] && options[:match] != :word | |
401 | + dynamic_fields[options[:match]] = {type: default_type, index: true, analyzer: "searchkick_#{options[:match]}_index"} | |
402 | + end | |
403 | + | |
404 | + if word | |
405 | + dynamic_fields[:analyzed] = analyzed_field_options | |
406 | + end | |
407 | + end | |
408 | + | |
409 | + # http://www.elasticsearch.org/guide/reference/mapping/multi-field-type/ | |
410 | + multi_field = dynamic_fields["{name}"].merge(fields: dynamic_fields.except("{name}")) | |
411 | + | |
412 | + mappings = { | |
413 | + properties: mapping, | |
414 | + _routing: routing, | |
415 | + # https://gist.github.com/kimchy/2898285 | |
416 | + dynamic_templates: [ | |
417 | + { | |
418 | + string_template: { | |
419 | + match: "*", | |
420 | + match_mapping_type: "string", | |
421 | + mapping: multi_field | |
422 | + } | |
423 | + } | |
424 | + ] | |
425 | + } | |
426 | + | |
427 | + if below70 | |
428 | + mappings = {index_type => mappings} | |
429 | + end | |
430 | + | |
431 | + mappings | |
432 | + end | |
433 | + | |
436 | 434 | def add_synonyms(settings) |
437 | 435 | synonyms = options[:synonyms] || [] |
438 | 436 | synonyms = synonyms.call if synonyms.respond_to?(:call) |
... | ... | @@ -499,6 +497,13 @@ module Searchkick |
499 | 497 | end |
500 | 498 | end |
501 | 499 | |
500 | + def set_deep_paging(settings) | |
501 | + if !settings.dig(:index, :max_result_window) && !settings[:"index.max_result_window"] | |
502 | + settings[:index] ||= {} | |
503 | + settings[:index][:max_result_window] = 1_000_000_000 | |
504 | + end | |
505 | + end | |
506 | + | |
502 | 507 | def default_type |
503 | 508 | "text" |
504 | 509 | end | ... | ... |