Extremely lightweight adapter between Rails and Solr.
SimpleSolr uses the REST interface that Solr offers and makes a great number of assumptions. This has resulted in a very fast, very lightweight library almost anyone can use straight away. It does mean you will be working with query strings and hashes directly, instead of with Ruby objects.
SimpleSolr is ideal when the Solr you use has been provided by a third party and is more or less running fine without you.
Design goals and benefits of SimpleSolr
-
only a few dozen lines of code
-
extremely simple DSL
-
only depends on httparty
-
can handle all common use cases
-
has support for master/slave configurations
-
does not come with a bundled Solr
-
does not send a bunch of magic fields
And my personal favorite:
-
no operation in unconfigured environments
If you have no development
section in the config file (see below) then nothing will happen at all. Your models will not be indexed, but you are freed from having to run a local Solr instance as well.
I owe a great deal to @outoftime’s Sunspot library. The configuration is identical, so if you come from that you will feel right at home. If you do need a fully-packed solution that is a good Ruby/Rails citizen and handles every Solr case you might have, use that instead.
Installation
Rails 2, in config/environment.rb
:
config.gem 'simple_solr'
Rails 3, in Gemfile
:
gem 'simple_solr'
Configuration
Create a file called config/simple_solr.yml
. (No, there is no generator. You can do it by hand, I believe in you.)
production:
solr:
hostname: "slave.local"
port: 8000
path: "/solr"
master_solr:
hostname: "master.local"
port: 8000
path: "/solr"
If you have just one Solr server, leave out the master_solr section.
Reasonable defaults are assumed for all these entries, so you can get away with just your environment and solr
key in there. You can leave out values in the master_solr
section, since the gem will fall back to using values from the solr
section instead.
Your models
Note: in these examples I am using a class called Document. This is just for illustrative purpuses, your class will probably have a different name, like Post or Product. You get the idea.
In your models include the following:
class Document < ActiveRecord::Base
simple_solr do
field :title
end
end
Only the fields listed in the simple_solr
block will be sent to Solr, with the addition of the id
field which is always included. Every field is passed to Builder, which has limited type casting. If you have special needs with regards to date/time formats or anything like that, use a lambda to manipulate the field to your liking.
Full example:
class FullDocument < ActiveRecord::Base
simple_solr do
field :id, lambda { |record| "full-document-#{record.id}" }
field :title
field :date_creation, :created_at
field :shared, false
field :publisher, "Megacorp LLC"
field :body
end
end
As you can see you have a couple options with regards to the fields:
-
Do nothing - in which case the corresponding attribute is used
-
A symbol - uses the instance method with that name as the value
-
Static value such as a string or boolean - which is used verbatim
-
A lambda - for your every customization need.
Use the latter if you want to add a dynamic field to Solr. The model instance is passed as a parameter, so Bob’s your uncle and the sky’s the limit.
Debugging
If something isn’t quite working, set httparty’s debug_output
flag on your model:
Document.debug_output
and then save the model to see the HTTP conversation on $stdout.
Searching
Use the simple_search
class method on your model:
Document.simple_search 'apple'
This will make a trip to Solr and return the results as a hash. That’s right. The results are not correlated with your models. In fact, no processing is done at all. Simple, right? If you need to fetch model instances based on the results, that is up to you.
You can add parameters, for example if you want to limit results using fq
:
Document.simple_search 'apple', :fq => "category:fruit"
See the Solr documentation for a list of common query parameters. Just remember that the q
parameter will be set already, although it can be overriden by the parameters you provide.
The response from Solr will look something like this:
<?xml version="1.0" encoding="UTF-8"?>
<response>
<lst name="responseHeader">
<int name="status">0</int>
<int name="QTime">3</int>
</lst>
<result name="response" numFound="1" start="0" maxScore="13.722203">
<doc>
<float name="score">13.722203</float>
<date name="date_creation">2011-01-06T23:02:33Z</date>
<str name="id">969</str>
<str name="publisher">Widgets, Inc</str>
<str name="title">Golden Delicious</str>
<str name="category">Apples</str>
</doc>
</result>
<lst name="highlighting">
<lst name="969"/>
</lst>
</response>
This response will be translated into a hash by httparty. Take a look at your webserver config/response headers if that does not happen.
Working in batches
If you want to add a bunch of existing models to Solr, you can:
Document.all.each do |document|
document.add_to_solr
end
Helping out
Interested in working on SimpleSolr? Please see DEVELOPMENT.rdoc.