Pluggable Search Components with Search API and FacetAPI
Pluggable Search Components with Search API and FacetAPI
09/28/2011 - 11:45
drupal
drupal7
planet drupal
modules
A great opportunity arose a few months back when Tom Nightingale and I were each beginning work on client sites needing advanced search functionality: the Search API module, providing "a framework for easily creating searches on any entity known to Drupal, using any kind of search engine" was becoming more awesome and more stable by the day, and the FacetAPI module had just been announced, but there was no integration between the two.
The attraction to Search API, for the project I was working on at least, arose from some initial uncertainty around whether we'd be using Sphinx or Apache Solr for the backend, and from the fact that we definitely wanted to use a Views front-end for displaying search results.
As for faceting, both Tom's project and mine had "collapsible" facets in their designs, something that had already been done on a previous Affinity Bridge client site that used Searchlight on Drupal 6, but it had been implemented as part of the theme. FacetAPI module was offering, among other great features, the possibility of recreating these collapsible facets as a widget that could be re-used across multiple sites.
An issue had already been posted in the Search API issue queue about integrating with FacetAPI, so I jumped in and declared my eagerness to work on it. After several initial iterations of the patch, with tremendous support from Thomas Seidl, author of Search API, and Chris Pliakas, author of FacetAPI, the work was moved into a separate sandbox project where it was easier to collaborate on; and now, a mere 3 months later, the two modules are happily joined in API matrimony.
So what?
So, these are two incredibly awesome modules that you can now use together to create a really great search experience. While the whole is certainly greater than the sum of its parts, it is worthwhile extolling the virtues of each part. I should point out, however, that neither module as a full release yet - Search API being held up mainly by Entity API.
Search API
This is a beautifully architected module that abstracts out all of the concepts involved in the process of site search. Implementations for common backends, e.g. the database and Apache Solr, are provided as separate modules, and the admin UI allows you to add as many search servers and indexes as your site could possibly require (by index here I mean a definition of how your site content is to be indexed - and although each index is associated with a particular server, the latter can be swapped out). To illustrate, your site could have a faceted View page powered by Apache Solr, another one powered by the database, and a block in the sidebar on both of these pages powered by Xapian.
Each backend declares which features it supports, e.g. faceting, autocomplete or spellcheck; and all Search API needs to know is that it supports a given feature, not how it supports it (it is an API module, after all). One of the main things this meant for me, once I'd decided on Solr for a backend, was that contrary to my expectation to have to tweak the solrconfig.xml and schema.xml files (files governing the configuration and index definition, respectively, of the Solr instance) to get the exact behavior I needed, I could actually do everything via the UI - and everything I did via the UI could be exported to my search feature. Perfection.
FacetAPI
The FacetAPI module deals with the creation, management and display of facets for search results, independently of the search engine providing these results. Facets can be defined in different realms - a realm being a way of grouping facets together. The only realm that comes with the module is the block realm, allowing you to have each facet in its own block. For each facet you can decide such things as whether it uses OR or AND filtering, the maximum number of facet options to display, whether to display a facet link for documents that don't have a value for that field (the "missing" facet), which searches the facet should appear on, etc.
So now we have converted the "collapsible facets" css and javascript from our old D6 theme to a FacetAPI widget, Facetapi Collapsible, and written another add-on module that provides a new realm which allows you to put all facet links into one block, Facetapi Block, the latter being still very much a work in progress.
Putting it all together
I've set up an install profile with a search feature that you can use to get up and running with Search API and FacetAPI very quickly. These instructions assume you are familar with drush and drush make, and will help you build a brand new Drupal install with everything you need pre-configured, with the exception of the Solr instance. If this is your first time using Solr, don't worry - it's outrageously simple to set up and there are great instructions for doing so here - just do the bit under "Setup Apache Solr", no need to do the rest of it as it's all done for you in the searchtastic feature that comes with the install profile. So, from within a directory that will be the parent directory of your search site, run this little command:% drush make --working-copy "https://raw.github.com/affinitybridge/d7search/master/stub.make" d7search
This will grab Drupal core and the install profile, which includes another make file which grabs all the required contrib (for more information on building sites this way, read Shawn's recent Build Kit Abridged post). Now cd into the newly created d7search directory and install the site with the following command (making sure to substitute your real db username and password for [username] and [password] respectively):% drush site-install d7search --site-name="D7 Search" --db-url=mysql://[username]:[password]@localhost/d7search
Assuming you have set up a vhost for this site at d7search.local, login to the new site with the admin/admin creds and go to admin/config/search/search_api and you will see a server and an index set up. If you have solr up and running, then the "Solr Search" server should be able to contact it - click on its name to view its configuration and a message should be displayed at the top telling you that the Solr server could be reached.
Of course, we'll need some content on our site if we want to have anything to index, so go ahead and create some dummy content - from the command line, run:% drush genc --types=story,page,article 100
Then go back to admin/config/search/search_api and click the index's "edit" link and then select "status" from the options popup. On the status page it should tell you that all of your site's content needs to be indexed. Click on the index button as many times as it takes to index your content.
To see everything in action, you can now just go to d7search.local/search and see a page listing your content, with a keyword search block and a facet block in the right sidebar. Play around with keyword searches and facets and you should see that it works nicely.
To see and alter the facet configuration, go back to admin/config/search/search_api and once again click "edit" beside the "Content Search" index and then select "facets" from the options popup. You will see the list of enabled facets. You can enable some more (the list displayed corresponds to the list of fields that is being indexed, which itself can be altered by clicking on the "fields tab" - just remember to re-index again if you do make changes there). Click on the "configure display" link for one of the enabled facets. Here you can change pretty much everything you could possibly want to about the facet's behaviour and display. For example, change the widget used to display the facet - select "links" for just a regular old list of facet links instead of the collapsible list.
With Solr as a backend, you can take advantage of some great search features that it supports, such as spelling suggestions, "more like this" and "OR"-based facets. Let's change the country facet to an OR facet. From the facet settings page, click the "configure display" link for the "Country" facet. Under global settings on the facet config screen, you should see an option to change the filter operator from AND to OR. Go ahead and make this change and click "Save configuration". Now, back on the search page, when you select a country to filter by, you'll still have the other options visible, and clicking on another option will mean seeing results where country is option1 OR country is option2.
There are tons more configuration options both on the Search API side and on the FacetAPI side, but hopefully this has given you a flavour for how great these two modules are, both individually and combined.