Commit 2c9a0cb27384ce199e6a3725f1920873d8a207fa
1 parent
c6e369a3
Exists in
master
and in
21 other branches
Return ActiveRecord objects
Showing
3 changed files
with
106 additions
and
101 deletions
Show diff stats
lib/searchkick/reindex.rb
... | ... | @@ -12,11 +12,11 @@ module Searchkick |
12 | 12 | # use scope for import |
13 | 13 | scope = respond_to?(:searchkick_import) ? searchkick_import : self |
14 | 14 | scope.find_in_batches do |batch| |
15 | - tire.index.import batch | |
15 | + index.import batch | |
16 | 16 | end |
17 | 17 | |
18 | 18 | if a = Tire::Alias.find(alias_name) |
19 | - old_indices = Tire::Alias.find(alias_name).indices | |
19 | + old_indices = a.indices.dup | |
20 | 20 | old_indices.each do |index| |
21 | 21 | a.indices.delete index |
22 | 22 | end |
... | ... | @@ -26,7 +26,7 @@ module Searchkick |
26 | 26 | |
27 | 27 | old_indices.each do |index| |
28 | 28 | i = Tire::Index.new(index) |
29 | - i.delete if i.exists? | |
29 | + i.delete | |
30 | 30 | end |
31 | 31 | else |
32 | 32 | i = Tire::Index.new(alias_name) | ... | ... |
lib/searchkick/search.rb
... | ... | @@ -8,131 +8,135 @@ module Searchkick |
8 | 8 | def search(term, options = {}) |
9 | 9 | fields = options[:fields] || ["_all"] |
10 | 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 | 29 | end |
28 | 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 | 38 | end |
37 | 39 | end |
38 | 40 | end |
39 | 41 | end |
40 | 42 | end |
41 | 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 | 55 | end |
54 | 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 | 82 | else |
96 | - raise "Unknown where operator" | |
83 | + filters << {not: {term: {field => op_value}}} | |
97 | 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 | 101 | end |
102 | + else | |
103 | + filters << {term: {field => value}} | |
100 | 104 | end |
101 | - else | |
102 | - filters << {term: {field => value}} | |
103 | 105 | end |
104 | 106 | end |
107 | + filters | |
105 | 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 | 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 | 132 | end |
131 | 133 | end |
132 | 134 | end |
133 | 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 | 140 | end |
137 | 141 | end |
138 | 142 | end | ... | ... |
test/searchkick_test.rb
... | ... | @@ -22,11 +22,12 @@ class Product < ActiveRecord::Base |
22 | 22 | end |
23 | 23 | end |
24 | 24 | |
25 | +Product.reindex | |
26 | + | |
25 | 27 | class TestSearchkick < Minitest::Unit::TestCase |
26 | 28 | |
27 | 29 | def setup |
28 | - Product.index.delete | |
29 | - Product.reindex | |
30 | + Product.destroy_all | |
30 | 31 | end |
31 | 32 | |
32 | 33 | # exact | ... | ... |