Thursday, November 22, 2007

Last month I've been working my a** off integrating Solr to our main site. The first step was to find out how to communicate with the Solr server. Naturally, I came to SolrSharp. But I found it to be really IoC-unfriendly: lots of inheritance, no interfaces, no unit-tests, so it would have been a real PITA to integrate it to Castle. So, instead of wrapping it, I built SolrNet.

Before explaining how it works, a disclaimer: I'm a complete newbie to Solr, Lucene and full-text searching in general. The code works on my machine and does what I need it to do for the task that I have at hand. This project is not, and might never be, feature complete like SolrSharp. Currently it doesn't support facets (UPDATE 8/20/08: I added facet support) or highlights, and maybe some other stuff. If you absolutely need those features right now, either use SolrSharp or write a patch for SolrNet. However, the next step in the integration is implementing faceted search, so I will definitely implement facets sooner or later.

Usage

First we have to map the Solr document to a class (Solr supports only one document type per instance at the moment). Let's use a subset of the default schema that comes with the Solr distribution:

It's just a POCO with a marker interface (ISolrDocument)[1] and some attributes: SolrField maps the attribute to a Solr field and SolrUniqueKey (optional) maps an attribute to a Solr unique key field. Let's add a document (make sure you have a running Solr instance first):

DSL

Since DSLs are such a hot topic nowadays, I decided to give it a try to see what happened. I just defined the syntax I wanted in a test, then wrote the interfaces to comply to the syntax and chain the methods, then built the implementations for those interfaces. The result is pretty much self-explanatory:

To execute the test, just invoke cscript on the WSF. Isn't it cool? Ok, ok, it's not cool at all, it only works for non-DOM javascript and only tests for internet explorer, BUT it's really simple and you get the potential to write the tests in another language[1], AND it can be easily integrated to a nant build with a <exec> task. In any case, it beats having no tests at all.

PS: Now seriously, go and check out the tools I mentioned above. GO GO!

[1] Doesn't really work most of the times. I tried ActivePython and ActiveRuby, but they don't see the functions exposed in jscript. Not to mention prototype modifications like the example above, since it doesn't make sense to other languages... VBScript seems to cooperate nicely but only for the most basic scenarios.