lib/searchkick/index.rb in searchkick-1.4.0 vs lib/searchkick/index.rb in searchkick-1.4.1
- old
+ new
@@ -65,10 +65,14 @@
def bulk_index(records)
Searchkick.queue_items(records.map { |r| {index: record_data(r).merge(data: search_data(r))} })
end
alias_method :import, :bulk_index
+ def bulk_update(records, method_name)
+ Searchkick.queue_items(records.map { |r| {update: record_data(r).merge(data: {doc: search_data(r, method_name)})} })
+ end
+
def record_data(r)
data = {
_index: name,
_id: search_id(r),
_type: document_type(r)
@@ -219,10 +223,11 @@
true
end
def import_scope(scope, options = {})
batch_size = @options[:batch_size] || 1000
+ method_name = options[:method_name]
# use scope for import
scope = scope.search_import if scope.respond_to?(:search_import)
if scope.respond_to?(:find_in_batches)
if options[:resume]
@@ -232,28 +237,32 @@
# TODO use primary key and prefix with table name
scope = scope.where("id > ?", total_docs)
end
scope.find_in_batches batch_size: batch_size do |batch|
- import batch.select(&:should_index?)
+ import_or_update batch.select(&:should_index?), method_name
end
else
# https://github.com/karmi/tire/blob/master/lib/tire/model/import.rb
# use cursor for Mongoid
items = []
# TODO add resume
scope.all.each do |item|
items << item if item.should_index?
if items.length == batch_size
- import items
+ import_or_update items, method_name
items = []
end
end
- import items
+ import_or_update items, method_name
end
end
+ def import_or_update(records, method_name)
+ method_name ? bulk_update(records, method_name) : import(records)
+ end
+
# other
def tokens(text, options = {})
client.indices.analyze({text: text, index: name}.merge(options))["tokens"].map { |t| t["token"] }
end
@@ -283,27 +292,28 @@
def search_id(record)
id = record.respond_to?(:search_document_id) ? record.search_document_id : record.id
id.is_a?(Numeric) ? id : id.to_s
end
- def search_data(record)
- source = record.search_data
+ def search_data(record, method_name = nil)
+ partial_reindex = !method_name.nil?
+ source = record.send(method_name || :search_data)
options = record.class.searchkick_options
# stringify fields
# remove _id since search_id is used instead
- source = source.each_with_object({}) { |(k, v), memo| memo[k.to_s] = v; memo }.except("_id")
+ source = source.each_with_object({}) { |(k, v), memo| memo[k.to_s] = v; memo }.except("_id", "_type")
# conversions
Array(options[:conversions]).map(&:to_s).each do |conversions_field|
if source[conversions_field]
source[conversions_field] = source[conversions_field].map { |k, v| {query: k, count: v} }
end
end
# hack to prevent generator field doesn't exist error
(options[:suggest] || []).map(&:to_s).each do |field|
- source[field] = nil unless source[field]
+ source[field] = nil if !source[field] && !partial_reindex
end
# locations
(options[:locations] || []).map(&:to_s).each do |field|
if source[field]