Commit 2c9a0cb27384ce199e6a3725f1920873d8a207fa

Authored by Andrew Kane
1 parent c6e369a3

Return ActiveRecord objects

lib/searchkick/reindex.rb
@@ -12,11 +12,11 @@ module Searchkick @@ -12,11 +12,11 @@ module Searchkick
12 # use scope for import 12 # use scope for import
13 scope = respond_to?(:searchkick_import) ? searchkick_import : self 13 scope = respond_to?(:searchkick_import) ? searchkick_import : self
14 scope.find_in_batches do |batch| 14 scope.find_in_batches do |batch|
15 - tire.index.import batch 15 + index.import batch
16 end 16 end
17 17
18 if a = Tire::Alias.find(alias_name) 18 if a = Tire::Alias.find(alias_name)
19 - old_indices = Tire::Alias.find(alias_name).indices 19 + old_indices = a.indices.dup
20 old_indices.each do |index| 20 old_indices.each do |index|
21 a.indices.delete index 21 a.indices.delete index
22 end 22 end
@@ -26,7 +26,7 @@ module Searchkick @@ -26,7 +26,7 @@ module Searchkick
26 26
27 old_indices.each do |index| 27 old_indices.each do |index|
28 i = Tire::Index.new(index) 28 i = Tire::Index.new(index)
29 - i.delete if i.exists? 29 + i.delete
30 end 30 end
31 else 31 else
32 i = Tire::Index.new(alias_name) 32 i = Tire::Index.new(alias_name)
lib/searchkick/search.rb
@@ -8,131 +8,135 @@ module Searchkick @@ -8,131 +8,135 @@ module Searchkick
8 def search(term, options = {}) 8 def search(term, options = {})
9 fields = options[:fields] || ["_all"] 9 fields = options[:fields] || ["_all"]
10 operator = options[:partial] ? "or" : "and" 10 operator = options[:partial] ? "or" : "and"
11 - tire.search load: true do  
12 - query do  
13 - boolean do  
14 - must do  
15 - dis_max do  
16 - query do  
17 - match fields, term, boost: 10, operator: operator, analyzer: "searchkick_search"  
18 - end  
19 - query do  
20 - match fields, term, boost: 10, operator: operator, analyzer: "searchkick_search2"  
21 - end  
22 - query do  
23 - match fields, term, use_dis_max: false, fuzziness: 0.7, max_expansions: 1, prefix_length: 1, operator: operator, analyzer: "searchkick_search"  
24 - end  
25 - query do  
26 - match fields, term, use_dis_max: false, fuzziness: 0.7, max_expansions: 1, prefix_length: 1, operator: operator, analyzer: "searchkick_search2" 11 + results =
  12 + tire.search do
  13 + query do
  14 + boolean do
  15 + must do
  16 + dis_max do
  17 + query do
  18 + match fields, term, boost: 10, operator: operator, analyzer: "searchkick_search"
  19 + end
  20 + query do
  21 + match fields, term, boost: 10, operator: operator, analyzer: "searchkick_search2"
  22 + end
  23 + query do
  24 + match fields, term, use_dis_max: false, fuzziness: 0.7, max_expansions: 1, prefix_length: 1, operator: operator, analyzer: "searchkick_search"
  25 + end
  26 + query do
  27 + match fields, term, use_dis_max: false, fuzziness: 0.7, max_expansions: 1, prefix_length: 1, operator: operator, analyzer: "searchkick_search2"
  28 + end
27 end 29 end
28 end 30 end
29 - end  
30 - if options[:conversions]  
31 - should do  
32 - nested path: "conversions", score_mode: "total" do  
33 - query do  
34 - custom_score script: "log(doc['count'].value)" do  
35 - match "query", term 31 + if options[:conversions]
  32 + should do
  33 + nested path: "conversions", score_mode: "total" do
  34 + query do
  35 + custom_score script: "log(doc['count'].value)" do
  36 + match "query", term
  37 + end
36 end 38 end
37 end 39 end
38 end 40 end
39 end 41 end
40 end 42 end
41 end 43 end
42 - end  
43 - # fields "_id", "_type", "name" # only return _id and _type - http://www.elasticsearch.org/guide/reference/api/search/fields/  
44 - size options[:limit] || 100000 # return all - like sql query  
45 - from options[:offset] if options[:offset]  
46 - explain options[:explain] if options[:explain] 44 + # fields "_id", "_type", "name" # only return _id and _type - http://www.elasticsearch.org/guide/reference/api/search/fields/
  45 + size options[:limit] || 100000 # return all - like sql query
  46 + from options[:offset] if options[:offset]
  47 + explain options[:explain] if options[:explain]
47 48
48 - # order  
49 - if options[:order]  
50 - sort do  
51 - options[:order].each do |k, v|  
52 - by k, v 49 + # order
  50 + if options[:order]
  51 + sort do
  52 + options[:order].each do |k, v|
  53 + by k, v
  54 + end
53 end 55 end
54 end 56 end
55 - end  
56 57
57 - # where  
58 - # TODO expand or 58 + # where
  59 + # TODO expand or
59 60
60 - where_filters =  
61 - proc do |where|  
62 - filters = []  
63 - (where || {}).each do |field, value|  
64 - if field == :or  
65 - value.each do |or_clause|  
66 - filters << {or: or_clause.map{|or_statement| {term: or_statement} }}  
67 - end  
68 - else  
69 - # expand ranges  
70 - if value.is_a?(Range)  
71 - value = {gte: value.first, (value.exclude_end? ? :lt : :lte) => value.last}  
72 - end 61 + where_filters =
  62 + proc do |where|
  63 + filters = []
  64 + (where || {}).each do |field, value|
  65 + if field == :or
  66 + value.each do |or_clause|
  67 + filters << {or: or_clause.map{|or_statement| {term: or_statement} }}
  68 + end
  69 + else
  70 + # expand ranges
  71 + if value.is_a?(Range)
  72 + value = {gte: value.first, (value.exclude_end? ? :lt : :lte) => value.last}
  73 + end
73 74
74 - if value.is_a?(Array) # in query  
75 - filters << {terms: {field => value}}  
76 - elsif value.is_a?(Hash)  
77 - value.each do |op, op_value|  
78 - if op == :not # not equal  
79 - if op_value.is_a?(Array)  
80 - filters << {not: {terms: {field => op_value}}}  
81 - else  
82 - filters << {not: {term: {field => op_value}}}  
83 - end  
84 - else  
85 - range_query =  
86 - case op  
87 - when :gt  
88 - {from: op_value, include_lower: false}  
89 - when :gte  
90 - {from: op_value, include_lower: true}  
91 - when :lt  
92 - {to: op_value, include_upper: false}  
93 - when :lte  
94 - {to: op_value, include_upper: true} 75 + if value.is_a?(Array) # in query
  76 + filters << {terms: {field => value}}
  77 + elsif value.is_a?(Hash)
  78 + value.each do |op, op_value|
  79 + if op == :not # not equal
  80 + if op_value.is_a?(Array)
  81 + filters << {not: {terms: {field => op_value}}}
95 else 82 else
96 - raise "Unknown where operator" 83 + filters << {not: {term: {field => op_value}}}
97 end 84 end
98 - filters << {range: {field => range_query}} 85 + else
  86 + range_query =
  87 + case op
  88 + when :gt
  89 + {from: op_value, include_lower: false}
  90 + when :gte
  91 + {from: op_value, include_lower: true}
  92 + when :lt
  93 + {to: op_value, include_upper: false}
  94 + when :lte
  95 + {to: op_value, include_upper: true}
  96 + else
  97 + raise "Unknown where operator"
  98 + end
  99 + filters << {range: {field => range_query}}
  100 + end
99 end 101 end
  102 + else
  103 + filters << {term: {field => value}}
100 end 104 end
101 - else  
102 - filters << {term: {field => value}}  
103 end 105 end
104 end 106 end
  107 + filters
105 end 108 end
106 - filters  
107 - end  
108 -  
109 - where_filters.call(options[:where]).each do |f|  
110 - type, value = f.first  
111 - filter type, value  
112 - end  
113 109
114 - # facets  
115 - if options[:facets]  
116 - facets = options[:facets] || {}  
117 - if facets.is_a?(Array) # convert to more advanced syntax  
118 - facets = Hash[ facets.map{|f| [f, {}] } ] 110 + where_filters.call(options[:where]).each do |f|
  111 + type, value = f.first
  112 + filter type, value
119 end 113 end
120 114
121 - facets.each do |field, facet_options|  
122 - facet_filters = where_filters.call(facet_options[:where])  
123 - facet field do  
124 - terms field  
125 - if facet_filters.size == 1  
126 - type, value = facet_filters.first.first  
127 - facet_filter type, value  
128 - elsif facet_filters.size > 1  
129 - facet_filter :and, *facet_filters 115 + # facets
  116 + if options[:facets]
  117 + facets = options[:facets] || {}
  118 + if facets.is_a?(Array) # convert to more advanced syntax
  119 + facets = Hash[ facets.map{|f| [f, {}] } ]
  120 + end
  121 +
  122 + facets.each do |field, facet_options|
  123 + facet_filters = where_filters.call(facet_options[:where])
  124 + facet field do
  125 + terms field
  126 + if facet_filters.size == 1
  127 + type, value = facet_filters.first.first
  128 + facet_filter type, value
  129 + elsif facet_filters.size > 1
  130 + facet_filter :and, *facet_filters
  131 + end
130 end 132 end
131 end 133 end
132 end 134 end
133 end 135 end
134 136
135 - end 137 + result_ids = results.map(&:id)
  138 + models = Hash[ find(result_ids).map{|m| [m.id.to_s, m] } ]
  139 + result_ids.map{|id| models[id] }.compact
136 end 140 end
137 end 141 end
138 end 142 end
test/searchkick_test.rb
@@ -22,11 +22,12 @@ class Product &lt; ActiveRecord::Base @@ -22,11 +22,12 @@ class Product &lt; ActiveRecord::Base
22 end 22 end
23 end 23 end
24 24
  25 +Product.reindex
  26 +
25 class TestSearchkick < Minitest::Unit::TestCase 27 class TestSearchkick < Minitest::Unit::TestCase
26 28
27 def setup 29 def setup
28 - Product.index.delete  
29 - Product.reindex 30 + Product.destroy_all
30 end 31 end
31 32
32 # exact 33 # exact