-
6
Apr
I know, I know. No one uses Solr anymore. Except me. And the guy that maintains acts_as_solr. And all those people who talk about it on twitter. Okay, so there are still a few people using it. This is for them.
Just a quick note on how you can improve your user’s browsing experience in an app that uses acts_as_solr. Our app has been using acts_as_solr for a year or more now, and we’ve generally been happy with it. Re-indexing a big table can be painful, but we don’t really end up doing that very often.
The one area that was still causing us some pain was the inline indexing of objects. I think the standard solution for this issue has been to defer indexing when creating/updating/deleting and have a cron job scheduled to take care of it at regular intervals. And that both works and is relatively painless. But that solution negates one of the things I like about acts_as_solr, as compared to other search solutions, which is the fact that indexing can be real time.
Anyway, I’m getting a little long winded, all I wanted to do here was point out something that, in retrospect, might seem obvious to others.
Recently, for reasons unrelated to Solr, we implemented workling and starling so that we could background some tasks that were delaying (and in some cases, timing out) our users’ sessions. While I was working on it, I realized that we could use workling to background the inline solr indexing, allowing us to speed up save operations while still basically having real time indexing. Here’s how we did it (all of this assumes that you have workling installed and functioning):
First, we created app/workers/solr_worker.rb:
class SolrWorker < Workling::Base def index_object(options={}) object = options[:object_type].constantize.find_by_id(options[:object_id]) unless object.blank? object.solr_save end end def destroy_object_index(options={}) object = options[:object_type].constantize.find_by_id(options[:object_id]) unless object.blank? object.solr_destroy end end end
Next, in vendor/plugins/acts_as_solr/lib/instance_methods.rb, we added two methods:
def async_solr_save SolrWorker.async_index_object(:object_type => self.class.name, :object_id => self.id) end def async_solr_destroy SolrWorker.async_destroy_object_index(:object_type => self.class.name, :object_id => self.id) end
And, finally, in vendor/plugins/acts_as_solr/lib/acts_methods.rb, we changed two lines from this:
after_save :solr_save after_destroy :solr_destroy
To this:
after_save :async_solr_save after_destroy :async_solr_destroy
And that’s it. This solution has been in place for a couple of weeks now, and we’ve seen a real improvement.
- Published by James in: Programming
- If you like this blog please take a second from your precious time and subscribe to my rss feed!
Leave a Reply