Commit 4bf972324b2f77a68cbba47756855c63d9431fd6

Authored by Paulo Fidalgo
Committed by Andrew Kane
1 parent eeb21d7a

Fix infinite recursion on multi search (#1098)

When we retry a multi search, we should not perform subsequent retries,
otherwise we'll end in an inifite recursion if we don't have enough
matches.

In this commit, a new flag is added to mark the execution of a retry.
Also since we have a local variable and a method with the same name
`queries`, a rename was applied to the method argument to improve the
readability.
lib/searchkick/multi_search.rb
@@ -14,12 +14,12 @@ module Searchkick @@ -14,12 +14,12 @@ module Searchkick
14 14
15 private 15 private
16 16
17 - def perform_search(queries)  
18 - responses = client.msearch(body: queries.flat_map { |q| [q.params.except(:body), q.body] })["responses"] 17 + def perform_search(search_queries, perform_retry: true)
  18 + responses = client.msearch(body: search_queries.flat_map { |q| [q.params.except(:body), q.body] })["responses"]
19 19
20 retry_queries = [] 20 retry_queries = []
21 - queries.each_with_index do |query, i|  
22 - if query.retry_misspellings?(responses[i]) 21 + search_queries.each_with_index do |query, i|
  22 + if perform_retry && query.retry_misspellings?(responses[i])
23 query.send(:prepare) # okay, since we don't want to expose this method outside Searchkick 23 query.send(:prepare) # okay, since we don't want to expose this method outside Searchkick
24 retry_queries << query 24 retry_queries << query
25 else 25 else
@@ -28,10 +28,10 @@ module Searchkick @@ -28,10 +28,10 @@ module Searchkick
28 end 28 end
29 29
30 if retry_queries.any? 30 if retry_queries.any?
31 - perform_search(retry_queries) 31 + perform_search(retry_queries, perform_retry: false)
32 end 32 end
33 33
34 - queries 34 + search_queries
35 end 35 end
36 36
37 def client 37 def client
test/multi_search_test.rb
@@ -22,7 +22,7 @@ class MultiSearchTest &lt; Minitest::Test @@ -22,7 +22,7 @@ class MultiSearchTest &lt; Minitest::Test
22 22
23 def test_misspellings_below_unmet 23 def test_misspellings_below_unmet
24 store_names ["abc", "abd", "aee"] 24 store_names ["abc", "abd", "aee"]
25 - products = Product.search("abc", misspellings: {below: 2}, execute: false) 25 + products = Product.search("abc", misspellings: {below: 5}, execute: false)
26 Searchkick.multi_search([products]) 26 Searchkick.multi_search([products])
27 assert_equal ["abc", "abd"], products.map(&:name) 27 assert_equal ["abc", "abd"], products.map(&:name)
28 end 28 end