lib/tanker.rb in tanker-1.1.3 vs lib/tanker.rb in tanker-1.1.4
- old
+ new
@@ -101,22 +101,26 @@
# fetch values from index tank or just the type and id to instace results localy
options[:fetch] = "__type,__id"
options[:fetch] += ",#{fetch.join(',')}" if fetch
options[:snippet] = snippets.join(',') if snippets
+ # convert category_filters to a json string
+ options[:category_filters] = options[:category_filters].to_json if options[:category_filters]
+
search_on_fields = models.map{|model| model.tanker_config.indexes.map{|arr| arr[0]}.uniq}.flatten.uniq.join(":(#{query.to_s}) OR ")
- query = "#{search_on_fields}:(#{query.to_s}) OR __any:(#{query.to_s}) __type:(#{models.map(&:name).map {|name| "\"#{name.split('::').join(' ')}\"" }.join(' OR ')})"
+ query = "(#{search_on_fields}:(#{query.to_s}) OR __any:(#{query.to_s})) __type:(#{models.map(&:name).map {|name| "\"#{name.split('::').join(' ')}\"" }.join(' OR ')})"
options = { :start => paginate[:per_page] * (paginate[:page] - 1), :len => paginate[:per_page] }.merge(options) if paginate
results = index.search(query, options)
+ categories = results['facets'] if results.has_key?('facets')
instantiated_results = if (fetch || snippets)
instantiate_results_from_results(results, fetch, snippets)
else
instantiate_results_from_db(results)
end
- paginate === false ? instantiated_results : Pagination.create(instantiated_results, results['matches'], paginate)
+ paginate === false ? instantiated_results : Pagination.create(instantiated_results, results['matches'], paginate, categories)
end
protected
def instantiate_results_from_db(index_result)
@@ -131,17 +135,23 @@
acc
end
id_map.each do |klass, ids|
# replace the id list with an eager-loaded list of records for this model
- id_map[klass] = constantize(klass).find(ids)
+ klass_const = constantize(klass)
+ if klass_const.respond_to?('find_all_by_id')
+ id_map[klass] = klass_const.find_all_by_id(ids)
+ else
+ id_map[klass] = klass_const.find(ids)
+ end
end
# return them in order
- results.map do |result|
+ results = results.map do |result|
model, id = result["__type"], result["__id"]
id_map[model].detect {|record| id == record.id.to_s }
end
+ results.compact
end
def instantiate_results_from_results(index_result, fetch = false, snippets = false)
results = index_result['results']
return [] if results.empty?
@@ -268,23 +278,38 @@
class ModelConfig
attr_accessor :index_name
attr_accessor :options
def initialize(index_name, options, block)
- @index_name = index_name
- @options = options
- @indexes = []
- @variables = []
- @functions = {}
+ @index_name = index_name
+ @options = options
+ @indexes = []
+ @categories = []
+ @variables = []
+ @functions = {}
instance_exec &block
end
- def indexes(field = nil, &block)
- @indexes << [field, block] if field
+ def indexes(field = nil, options = {}, &block)
+ if field
+ @indexes << [field, block]
+ @categories << [field, block] if options[:category]
+ end
@indexes
end
+
+ def category(field = nil, options = {}, &block)
+ categories field, options, &block
+ end
+ def categories(field = nil, options = {}, &block)
+ if field
+ @categories << [field, block]
+ end
+ @categories
+ end
+
def variables(&block)
@variables << block if block
@variables
end
@@ -308,10 +333,14 @@
def tanker_indexes
tanker_config.indexes
end
+ def tanker_categories
+ tanker_config.categories
+ end
+
def tanker_variables
tanker_config.variables
end
# update a create instance from index tank
@@ -331,20 +360,20 @@
# attempt to autodetect timestamp
if respond_to?(:created_at)
data[:timestamp] = created_at.to_i
end
-
+
tanker_indexes.each do |field, block|
val = block ? instance_exec(&block) : send(field)
val = val.join(' ') if Array === val
data[field.to_sym] = val.to_s unless val.nil?
end
data[:__any] = data.values.sort_by{|v| v.to_s}.join " . "
data[:__type] = type_name
- data[:__id] = self.id
+ data[:__id] = self.id.is_a?(Fixnum) ? self.id : self.id.to_s
data
end
#dynamically create a snippet read attribute (method)
@@ -361,9 +390,18 @@
options[:variables] = tanker_variables.inject({}) do |hash, variables|
hash.merge(instance_exec(&variables))
end
end
+ unless tanker_categories.empty?
+ options[:categories] = {}
+ tanker_categories.each do |field, block|
+ val = block ? instance_exec(&block) : send(field)
+ val = val.join(' ') if Array === val
+ options[:categories][field] = val.to_s unless val.nil?
+ end
+ end
+
options
end
# create a unique index based on the model name and unique id
def it_doc_id