A reliable search engine is a default requirement for any selfrespecting website nowadays. This project always had a SearchBundle, but its implementation was flawed: both in setup as in third party libraries used. We totally rebuilt this version from the ground up on top of ElasticSearch (a Lucene based search engine) and Sherlock. We won't go into the details of running ElasticSearch in your dev and production environment but in most cases it's as easy as installing it using your packagemanager of choice.

Installation

The KunstmaanSearchBundle provides the interface with ElasticSearch using Sherlock as the client library. The KunstmaanNodeSearchBundle uses the SearchBundle to create an index and populate them with the nodes of your website. It also uses Sherlock to build the mappings.
 
Add the following 2 lines to your composer.json and run composer update.
"kunstmaan/search-bundle": "dev-master",
"kunstmaan/node-search-bundle": "dev-master",
Add both bundles to your AppKernel.php:
// KunstmaanSearchBundle
$bundles[] = new Kunstmaan\SearchBundle\KunstmaanSearchBundle();
// KunstmaanNodeSearchBundle
$bundles[] = new Kunstmaan\NodeSearchBundle\KunstmaanNodeSearchBundle();

The KunstmaanGeneratorBundle allows you to generate a SearchPage for your website bundle. I'm assuming you followed the Getting Started Guide and generated a default website. Even if that's not the case, this tutorial will also help you implement your custom Kunstmaan Bundles.

Perform the following command in your console to generate a SearchPage and its templates in your WebsiteBundle (in Entity\Pages\Search).

app/console kuma:generate:searchpage --namespace=ProjectName/WebsiteBundle

The next step is to add your newly generated SearchPage as a possible child to one of your existing pages. In this example we've chosen to add it under the Homepage: edit the Homepage class and add it to the getPossibleChildTypes method.

/**
 * @return array
 */
public function getPossibleChildTypes()
{
    return array(
        array(
            'name' => 'Search',
            'class'=> "ProjectName\WebsiteBundle\Entity\Pages\Search\SearchPage"
        )
    );
}

Don't forget to update your database schema before trying to add the page in your admin. This can be easily done by the following command or you can choose to work with migrations.

app/console doctrine:schema:update --force

When your database schema has been updated, you can log in to your admin, go to the page you wish to add the SearchPage to and create it.

Creating and populating the index

All you need to do now is set up your index and populate it. This can be done easily using the following commands.
app/console kuma:search:setup
app/console kuma:search:populate

This last command can be rerun every time you want to update your index with new content. But, you won't need to do this for your nodes. Upon saving, publishing, deleting and unpublishing your pages, the index will automatically be updated to reflect these changes. Needless to say, only published pages will be indexed.

Searching

You now have a SearchPage on your website. Search results are paginated 10 results per page, for each result it will show the title and a highlighted best fragment of the search. On the right (or wherever you want to place them) you'll see the option to filter these results by their tags. These facets are automatically generated when your page implements the Taggable interface (see this Tagging blog entry on how to add tags to your pages). You can enable multiple tags at once and filter as much as you want.

The search capabilities you now have on your website are basic but very useful. You can start to expand your search to customize it any way you want.

If you like this post, you should check out my series on creating a full featured blog, and recommend these bundles on KnpBundles!