Commit 2054a2bbb35fe5168c3bd526448f50e308869b66

Authored by Andrew Kane
1 parent 89502e6b

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]
... ...