Commit 2054a2bbb35fe5168c3bd526448f50e308869b66
1 parent
89502e6b
Exists in
master
and in
5 other branches
Improved missing_ids code
Showing
1 changed file
with
75 additions
and
71 deletions
Show diff stats
lib/searchkick/results.rb
... | ... | @@ -21,80 +21,11 @@ module Searchkick |
21 | 21 | |
22 | 22 | # TODO return enumerator like with_score |
23 | 23 | def with_hit |
24 | - @with_hit ||= begin | |
25 | - @missing_ids = [] | |
26 | - | |
27 | - if options[:load] | |
28 | - # results can have different types | |
29 | - results = {} | |
30 | - | |
31 | - hits.group_by { |hit, _| hit["_index"] }.each do |index, grouped_hits| | |
32 | - klasses = | |
33 | - if @klass | |
34 | - [@klass] | |
35 | - else | |
36 | - index_alias = index.split("_")[0..-2].join("_") | |
37 | - Array((options[:index_mapping] || {})[index_alias]) | |
38 | - end | |
39 | - raise Searchkick::Error, "Unknown model for index: #{index}" unless klasses.any? | |
40 | - | |
41 | - results[index] = {} | |
42 | - klasses.each do |klass| | |
43 | - results[index].merge!(results_query(klass, grouped_hits).to_a.index_by { |r| r.id.to_s }) | |
44 | - end | |
45 | - end | |
46 | - | |
47 | - # sort | |
48 | - results = | |
49 | - hits.map do |hit| | |
50 | - result = results[hit["_index"]][hit["_id"].to_s] | |
51 | - if result && !(options[:load].is_a?(Hash) && options[:load][:dumpable]) | |
52 | - if (hit["highlight"] || options[:highlight]) && !result.respond_to?(:search_highlights) | |
53 | - highlights = hit_highlights(hit) | |
54 | - result.define_singleton_method(:search_highlights) do | |
55 | - highlights | |
56 | - end | |
57 | - end | |
58 | - end | |
59 | - [result, hit] | |
60 | - end.select do |result, hit| | |
61 | - @missing_ids << hit["_id"] unless result | |
62 | - result | |
63 | - end | |
64 | - | |
65 | - if @missing_ids.any? | |
66 | - Searchkick.warn("Records in search index do not exist in database: #{@missing_ids.join(", ")}") | |
67 | - end | |
68 | - | |
69 | - results | |
70 | - else | |
71 | - hits.map do |hit| | |
72 | - result = | |
73 | - if hit["_source"] | |
74 | - hit.except("_source").merge(hit["_source"]) | |
75 | - elsif hit["fields"] | |
76 | - hit.except("fields").merge(hit["fields"]) | |
77 | - else | |
78 | - hit | |
79 | - end | |
80 | - | |
81 | - if hit["highlight"] || options[:highlight] | |
82 | - highlight = Hash[hit["highlight"].to_a.map { |k, v| [base_field(k), v.first] }] | |
83 | - options[:highlighted_fields].map { |k| base_field(k) }.each do |k| | |
84 | - result["highlighted_#{k}"] ||= (highlight[k] || result[k]) | |
85 | - end | |
86 | - end | |
87 | - | |
88 | - result["id"] ||= result["_id"] # needed for legacy reasons | |
89 | - [HashWrapper.new(result), hit] | |
90 | - end | |
91 | - end | |
92 | - end | |
24 | + @with_hit ||= with_hit_and_missing_ids[0] | |
93 | 25 | end |
94 | 26 | |
95 | 27 | def missing_ids |
96 | - with_hit | |
97 | - @missing_ids | |
28 | + @missing_ids ||= with_hit_and_missing_ids[1] | |
98 | 29 | end |
99 | 30 | |
100 | 31 | def suggestions |
... | ... | @@ -283,6 +214,79 @@ module Searchkick |
283 | 214 | |
284 | 215 | private |
285 | 216 | |
217 | + def with_hit_and_missing_ids | |
218 | + @with_hit_and_missing_ids ||= begin | |
219 | + missing_ids = [] | |
220 | + | |
221 | + if options[:load] | |
222 | + # results can have different types | |
223 | + results = {} | |
224 | + | |
225 | + hits.group_by { |hit, _| hit["_index"] }.each do |index, grouped_hits| | |
226 | + klasses = | |
227 | + if @klass | |
228 | + [@klass] | |
229 | + else | |
230 | + index_alias = index.split("_")[0..-2].join("_") | |
231 | + Array((options[:index_mapping] || {})[index_alias]) | |
232 | + end | |
233 | + raise Searchkick::Error, "Unknown model for index: #{index}" unless klasses.any? | |
234 | + | |
235 | + results[index] = {} | |
236 | + klasses.each do |klass| | |
237 | + results[index].merge!(results_query(klass, grouped_hits).to_a.index_by { |r| r.id.to_s }) | |
238 | + end | |
239 | + end | |
240 | + | |
241 | + # sort | |
242 | + results = | |
243 | + hits.map do |hit| | |
244 | + result = results[hit["_index"]][hit["_id"].to_s] | |
245 | + if result && !(options[:load].is_a?(Hash) && options[:load][:dumpable]) | |
246 | + if (hit["highlight"] || options[:highlight]) && !result.respond_to?(:search_highlights) | |
247 | + highlights = hit_highlights(hit) | |
248 | + result.define_singleton_method(:search_highlights) do | |
249 | + highlights | |
250 | + end | |
251 | + end | |
252 | + end | |
253 | + [result, hit] | |
254 | + end.select do |result, hit| | |
255 | + missing_ids << hit["_id"] unless result | |
256 | + result | |
257 | + end | |
258 | + | |
259 | + if missing_ids.any? | |
260 | + Searchkick.warn("Records in search index do not exist in database: #{missing_ids.join(", ")}") | |
261 | + end | |
262 | + else | |
263 | + results = | |
264 | + hits.map do |hit| | |
265 | + result = | |
266 | + if hit["_source"] | |
267 | + hit.except("_source").merge(hit["_source"]) | |
268 | + elsif hit["fields"] | |
269 | + hit.except("fields").merge(hit["fields"]) | |
270 | + else | |
271 | + hit | |
272 | + end | |
273 | + | |
274 | + if hit["highlight"] || options[:highlight] | |
275 | + highlight = Hash[hit["highlight"].to_a.map { |k, v| [base_field(k), v.first] }] | |
276 | + options[:highlighted_fields].map { |k| base_field(k) }.each do |k| | |
277 | + result["highlighted_#{k}"] ||= (highlight[k] || result[k]) | |
278 | + end | |
279 | + end | |
280 | + | |
281 | + result["id"] ||= result["_id"] # needed for legacy reasons | |
282 | + [HashWrapper.new(result), hit] | |
283 | + end | |
284 | + end | |
285 | + | |
286 | + [results, missing_ids] | |
287 | + end | |
288 | + end | |
289 | + | |
286 | 290 | def results_query(records, hits) |
287 | 291 | ids = hits.map { |hit| hit["_id"] } |
288 | 292 | if options[:includes] || options[:model_includes] | ... | ... |