rake sunspot:reindex
如果是只reindex其中一個model,可以下:
rake sunspot:reindex[,ModelName]
注意在zsh中要用\跳脫[]字元
rake sunspot:reindex\[,ModelName\]
在預設的sunspot設定下,只要是使用Searchable的model,在做儲存時,會自動更新這筆資料的index。但要注意的是,即使是沒更新任何attribute的值,只要呼叫到save,更新index的動作還是會進行,如果你的searchable中定義的field太複雜(例如有關聯到其它的model資料),那每一次儲存都會造成大量的query。
從下面的sunspot_rails原始碼可以發現,searchable會用到before_save與after_save這兩個callback,在before_save時去決定是否要做index,而在after_save去執行更新index的動作。
sunspot_rails-2.1.1/lib/sunspot/rails/searchable.rb:80def searchable(options = {}, &block)
Sunspot.setup(self, &block)
if searchable?
sunspot_options[:include].concat(Util::Array(options[:include]))
else
extend ClassMethods
include InstanceMethods
class_attribute :sunspot_options
unless options[:auto_index] == false
before_save :mark_for_auto_indexing_or_removal
after_save :perform_index_tasks
end
unless options[:auto_remove] == false
after_destroy do |searchable|
searchable.remove_from_index
end
end
options[:include] = Util::Array(options[:include])
self.sunspot_options = options
end
end
在before_save callback,會呼叫mark_for_auto_indexing_or_removal,我們可以發現sunspot提供很多的option來決定是否要做index。你甚至可以關掉自動index的功能,手動來控制index的行為。
sunspot_rails-2.1.1/lib/sunspot/rails/searchable.rb:461def mark_for_auto_indexing_or_removal
if indexable?
# :if/:unless constraints pass or were not present
@marked_for_auto_indexing =
if !new_record? && ignore_attributes = self.class.sunspot_options[:ignore_attribute_changes_of]
!(changed.map { |attr| attr.to_sym } - ignore_attributes).blank?
elsif !new_record? && only_attributes = self.class.sunspot_options[:only_reindex_attribute_changes_of]
!(changed.map { |attr| attr.to_sym } & only_attributes).blank?
else
true
end
@marked_for_auto_removal = false
else
# :if/:unless constraints did not pass; do not auto index and
# actually go one step further by removing it from the index
@marked_for_auto_indexing = false
@marked_for_auto_removal = true
end
true
end
def perform_index_tasks
if @marked_for_auto_indexing
solr_index
remove_instance_variable(:@marked_for_auto_indexing)
elsif @marked_for_auto_removal
solr_remove_from_index
remove_instance_variable(:@marked_for_auto_removal)
end
end
Sunspot.session = Sunspot::Rails::StubSessionProxy.new(Sunspot.session)
#
# ... 這裡寫你想執行的程式,但不會觸發reindex
#
Sunspot.session = Sunspot.session.original_session