diff --git a/lib/searchkick/reindex.rb b/lib/searchkick/reindex.rb index 67953f2..ff7ac0a 100644 --- a/lib/searchkick/reindex.rb +++ b/lib/searchkick/reindex.rb @@ -12,11 +12,11 @@ module Searchkick # use scope for import scope = respond_to?(:searchkick_import) ? searchkick_import : self scope.find_in_batches do |batch| - tire.index.import batch + index.import batch end if a = Tire::Alias.find(alias_name) - old_indices = Tire::Alias.find(alias_name).indices + old_indices = a.indices.dup old_indices.each do |index| a.indices.delete index end @@ -26,7 +26,7 @@ module Searchkick old_indices.each do |index| i = Tire::Index.new(index) - i.delete if i.exists? + i.delete end else i = Tire::Index.new(alias_name) diff --git a/lib/searchkick/search.rb b/lib/searchkick/search.rb index 87e8373..7ebd019 100644 --- a/lib/searchkick/search.rb +++ b/lib/searchkick/search.rb @@ -8,131 +8,135 @@ module Searchkick def search(term, options = {}) fields = options[:fields] || ["_all"] operator = options[:partial] ? "or" : "and" - tire.search load: true do - query do - boolean do - must do - dis_max do - query do - match fields, term, boost: 10, operator: operator, analyzer: "searchkick_search" - end - query do - match fields, term, boost: 10, operator: operator, analyzer: "searchkick_search2" - end - query do - match fields, term, use_dis_max: false, fuzziness: 0.7, max_expansions: 1, prefix_length: 1, operator: operator, analyzer: "searchkick_search" - end - query do - match fields, term, use_dis_max: false, fuzziness: 0.7, max_expansions: 1, prefix_length: 1, operator: operator, analyzer: "searchkick_search2" + results = + tire.search do + query do + boolean do + must do + dis_max do + query do + match fields, term, boost: 10, operator: operator, analyzer: "searchkick_search" + end + query do + match fields, term, boost: 10, operator: operator, analyzer: "searchkick_search2" + end + query do + match fields, term, use_dis_max: false, fuzziness: 0.7, max_expansions: 1, prefix_length: 1, operator: operator, analyzer: "searchkick_search" + end + query do + match fields, term, use_dis_max: false, fuzziness: 0.7, max_expansions: 1, prefix_length: 1, operator: operator, analyzer: "searchkick_search2" + end end end - end - if options[:conversions] - should do - nested path: "conversions", score_mode: "total" do - query do - custom_score script: "log(doc['count'].value)" do - match "query", term + if options[:conversions] + should do + nested path: "conversions", score_mode: "total" do + query do + custom_score script: "log(doc['count'].value)" do + match "query", term + end end end end end end end - end - # fields "_id", "_type", "name" # only return _id and _type - http://www.elasticsearch.org/guide/reference/api/search/fields/ - size options[:limit] || 100000 # return all - like sql query - from options[:offset] if options[:offset] - explain options[:explain] if options[:explain] + # fields "_id", "_type", "name" # only return _id and _type - http://www.elasticsearch.org/guide/reference/api/search/fields/ + size options[:limit] || 100000 # return all - like sql query + from options[:offset] if options[:offset] + explain options[:explain] if options[:explain] - # order - if options[:order] - sort do - options[:order].each do |k, v| - by k, v + # order + if options[:order] + sort do + options[:order].each do |k, v| + by k, v + end end end - end - # where - # TODO expand or + # where + # TODO expand or - where_filters = - proc do |where| - filters = [] - (where || {}).each do |field, value| - if field == :or - value.each do |or_clause| - filters << {or: or_clause.map{|or_statement| {term: or_statement} }} - end - else - # expand ranges - if value.is_a?(Range) - value = {gte: value.first, (value.exclude_end? ? :lt : :lte) => value.last} - end + where_filters = + proc do |where| + filters = [] + (where || {}).each do |field, value| + if field == :or + value.each do |or_clause| + filters << {or: or_clause.map{|or_statement| {term: or_statement} }} + end + else + # expand ranges + if value.is_a?(Range) + value = {gte: value.first, (value.exclude_end? ? :lt : :lte) => value.last} + end - if value.is_a?(Array) # in query - filters << {terms: {field => value}} - elsif value.is_a?(Hash) - value.each do |op, op_value| - if op == :not # not equal - if op_value.is_a?(Array) - filters << {not: {terms: {field => op_value}}} - else - filters << {not: {term: {field => op_value}}} - end - else - range_query = - case op - when :gt - {from: op_value, include_lower: false} - when :gte - {from: op_value, include_lower: true} - when :lt - {to: op_value, include_upper: false} - when :lte - {to: op_value, include_upper: true} + if value.is_a?(Array) # in query + filters << {terms: {field => value}} + elsif value.is_a?(Hash) + value.each do |op, op_value| + if op == :not # not equal + if op_value.is_a?(Array) + filters << {not: {terms: {field => op_value}}} else - raise "Unknown where operator" + filters << {not: {term: {field => op_value}}} end - filters << {range: {field => range_query}} + else + range_query = + case op + when :gt + {from: op_value, include_lower: false} + when :gte + {from: op_value, include_lower: true} + when :lt + {to: op_value, include_upper: false} + when :lte + {to: op_value, include_upper: true} + else + raise "Unknown where operator" + end + filters << {range: {field => range_query}} + end end + else + filters << {term: {field => value}} end - else - filters << {term: {field => value}} end end + filters end - filters - end - - where_filters.call(options[:where]).each do |f| - type, value = f.first - filter type, value - end - # facets - if options[:facets] - facets = options[:facets] || {} - if facets.is_a?(Array) # convert to more advanced syntax - facets = Hash[ facets.map{|f| [f, {}] } ] + where_filters.call(options[:where]).each do |f| + type, value = f.first + filter type, value end - facets.each do |field, facet_options| - facet_filters = where_filters.call(facet_options[:where]) - facet field do - terms field - if facet_filters.size == 1 - type, value = facet_filters.first.first - facet_filter type, value - elsif facet_filters.size > 1 - facet_filter :and, *facet_filters + # facets + if options[:facets] + facets = options[:facets] || {} + if facets.is_a?(Array) # convert to more advanced syntax + facets = Hash[ facets.map{|f| [f, {}] } ] + end + + facets.each do |field, facet_options| + facet_filters = where_filters.call(facet_options[:where]) + facet field do + terms field + if facet_filters.size == 1 + type, value = facet_filters.first.first + facet_filter type, value + elsif facet_filters.size > 1 + facet_filter :and, *facet_filters + end end end end end - end + result_ids = results.map(&:id) + models = Hash[ find(result_ids).map{|m| [m.id.to_s, m] } ] + result_ids.map{|id| models[id] }.compact end end end diff --git a/test/searchkick_test.rb b/test/searchkick_test.rb index da48fd3..67352f7 100644 --- a/test/searchkick_test.rb +++ b/test/searchkick_test.rb @@ -22,11 +22,12 @@ class Product < ActiveRecord::Base end end +Product.reindex + class TestSearchkick < Minitest::Unit::TestCase def setup - Product.index.delete - Product.reindex + Product.destroy_all end # exact -- libgit2 0.21.0