# Introduction
sfLucene integrates Zend_Search_Lucene and sfSearch to create a backend engine.

# Dependencies
* sfSearchPlugin

# Features
* Stemming for English
* Fully unit tested

# Installation
* sfLucene is currently available from subversion only:

        svn co http://svn.symfony-project.com/plugins/sfSearchPlugin/trunk/lucene plugins/sfLucenePlugin 

* You will also need sfSearchPlugin:

        svn co http://svn.symfony-project.com/plugins/sfSearchPlugin/trunk/core plugins/sfSearchPlugin

# Setup
Configuring sfLucene to work with sfSearch is very simple.  All we must do is set the engine:

    <?php
    class MySearchIndex extends xfIndexSingle
    {
    protected function configure()
    {
        // service registry setup here

        $engine = new xfLuceneEngine(sfConfig::get('sf_data_dir') . '/index/MyIndex');
        $this->setEngine($engine);
    }
    }

As you can see, the constructor to xfLuceneEngine takes a path to where the index should be stored.

At this point, you can begin populating your index and searching. But, there are more configuration options if you desire.

## Analyzers
An analyzer looks at your index and determines how to index and match text.  For example, some analyzers can only handle ASCII text, some ignore numbers, and some are case sensitive.

You can specify an analyzer to use with the engine with the `->setAnalyzer()` method.  By default, sfLucene uses an analyzer that supports:
* UTF8 text
* Numbers
* Case insensitive

### Zend_Search_Lucene Analyzers
Zend_Search_Lucene provides many more analyzers. If you are not indexing accented text, you can save performance by using a plain ASCII analyzer.  Zend_Search_Lucene provides the following analyzers:

<table>
    <tr>
        <th>Analyzer</th>
        <th>UTF8?</th>
        <th>Numbers?</th>
        <th>Case Sensitive?</th>
        <th>Stemming?</th>
    </tr>
    <tr>
        <td>Zend_Search_Lucene_Analysis_Analyzer_Common_Text</td>
        <td>No</td>
        <td>No</td>
        <td>Yes</td>
        <td>No</td>
    </tr>
    <tr>
        <td>Zend_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive</td>
        <td>No</td>
        <td>No</td>
        <td>No</td>
        <td>No</td>
    </tr>
    <tr>
        <td>Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum</td>
        <td>No</td>
        <td>Yes</td>
        <td>Yes</td>
        <td>No</td>
    </tr>
    <tr>
        <td>Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum_CaseInsensitive</td>
        <td>No</td>
        <td>Yes</td>
        <td>No</td>
        <td>No</td>
    </tr>
    <tr>
        <td>Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8</td>
        <td>Yes</td>
        <td>No</td>
        <td>Yes</td>
        <td>No</td>
    </tr>
    <tr>
        <td>Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8_CaseInsensitive</td>
        <td>Yes</td>
        <td>No</td>
        <td>No</td>
        <td>No</td>
    <tr>
        <td>Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8Num</td>
        <td>Yes</td>
        <td>Yes</td>
        <td>Yes</td>
        <td>No</td>
    </tr>
    <tr>
        <td>Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8Num_CaseInsensitive</td>
        <td>Yes</td>
        <td>Yes</td>
        <td>No</td>
        <td>No</td>
    </tr>
</table>

We can set one of these analyzers like so:

    $engine->setAnalyzer(new Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum);

### xfLuceneAnalyzer
sfLucene provides an analyzer that makes it easy to configure your exact requirements that supports toggles for:
* UTF8 vs ASCII
* Numbers vs No Numbers
* Case Sensitive vs Case Insensitive
* Stemming vs No Stemming
* Short Words
* Stop Words

Using this analyzer is easy:

    $analyzer = new xfLuceneAnalyzer;
    $analyzer->setCaseInsensitive(); // makes case insensitive
    $analyzer->addStopWords(array('the', 'therefore')); // ignores these words
    $analyzer->addStopWordsFromFile('/path/to/file.txt'); // ignores these words in the file, one word per line
    $analyzer->setShortWordLength(2); // all words less than 2 characters are ignored

    $engine->setAnalyzer($analyzer);

## Stemming
A stemming algorithm takes a word and gets the root of the word.  For example, "happy" and "happiness" share the same stem.  Stemming is helpful for search engines because if the user searches for "happiness", they likely also want results that match "happy". 

sfLucene ships with a PHP implementation of the PorterStemmer algorithm, a popular stemming algorithm for English-based languages.  To use the PorterStemmer algorithm, we set it up like so:

    $analyzer = new xfLuceneAnalyzer;
    $analyzer->setStemmer(new xfLuceneStemmerPorter);

    $engine->setAnalyzer($analyzer);

If your index will not store English content or the PorterStemmer algorithm does not suit your needs, it is easy to create your own stemmer.  We simply create a class that implements the xfLuceneStemmer interface:

    final class MyStemmer implements xfLuceneStemmer
    {
    public function doStem($word)
    {
        // stem the word here 

        return $word;
    }
    }

Then:

    $analyzer = new xfLuceneAnalyzer;
    $analyzer->setStemmer(new MyStemmer);

<!--
vim:ft=mkd
-->
