Extensibilidade Análise de Texto A classe Zend_Search_Lucene_Analysis_Analyzer é usada pelo indexador para separar em tokens os campos de texto do documento. Os métodos Zend_Search_Lucene_Analysis_Analyzer::getDefault() e Zend_Search_Lucene_Analysis_Analyzer::setDefault() são usados para obter e setar, respectivamente, o analisador padrão. Você pode atribuir o seu próprio analisador de textos ou selecioná-lo dentre uma lista de analisadores pré-definidos: Zend_Search_Lucene_Analysis_Analyzer_Common_Text e Zend_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive (padrão). Ambos interpretam os tokens como sequências de letras. Zend_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive converte todos os tokens para minúsculas. Para selecionar um analisador: addDocument($doc); ]]> A classe Zend_Search_Lucene_Analysis_Analyzer_Common foi projetada para ser um antepassado de todos os analisadores definidos pelo usuário. O usuário só precisa definir os métodos reset() e nextToken(), que receberá a string do membro $_input e retornará os tokens um por um (um valor NULL indica o fim do fluxo). O método nextToken() deve chamar o método normalize() em cada token. Isso te permite usar filtros de token junto com o seu analisador. Aqui está um exemplo de um analisador customizado, que aceita palavras contendo dígitos como termos: Analisador de Texto Customizado _position = 0; } /** * API do fluxo de separação de tokens * Obtém o próximo token * Retorna null no final do fluxo * * @return Zend_Search_Lucene_Analysis_Token|null */ public function nextToken() { if ($this->_input === null) { return null; } while ($this->_position < strlen($this->_input)) { // ignora os espaços em branco while ($this->_position < strlen($this->_input) && !ctype_alnum( $this->_input[$this->_position] )) { $this->_position++; } $termStartPosition = $this->_position; // lê o token while ($this->_position < strlen($this->_input) && ctype_alnum( $this->_input[$this->_position] )) { $this->_position++; } // Token vazio, fim do fluxo. if ($this->_position == $termStartPosition) { return null; } $token = new Zend_Search_Lucene_Analysis_Token( substr($this->_input, $termStartPosition, $this->_position - $termStartPosition), $termStartPosition, $this->_position); $token = $this->normalize($token); if ($token !== null) { return $token; } // Continua se o token for ignorado } return null; } } Zend_Search_Lucene_Analysis_Analyzer::setDefault( new My_Analyzer()); ]]> Filtragem de Tokens O analisador Zend_Search_Lucene_Analysis_Analyzer_Common também oferece um mecanismo de filtragem de token. A classe Zend_Search_Lucene_Analysis_TokenFilter fornece uma interface abstrata para estes filtros. Seus próprios filtros devem estender esta classe, diretamente ou indiretamente. Qualquer filtro personalizado deve implementar o método normalize() que pode transformar o token de entrada ou sinalizar que o token corrente deve ser ignorado. Aí estão três filtros já definidos no subpacote de análise: Zend_Search_Lucene_Analysis_TokenFilter_LowerCase Zend_Search_Lucene_Analysis_TokenFilter_ShortWords Zend_Search_Lucene_Analysis_TokenFilter_StopWords O filtro LowerCase já é utilizado pelo analisador Zend_Search_Lucene_Analysis_Analyzer_Common_Text_CaseInsensitive por padrão. Os filtros ShortWords e StopWords podem ser utilizados com analisadores pré-definidos ou personalizados desta forma: addFilter($stopWordsFilter); Zend_Search_Lucene_Analysis_Analyzer::setDefault($analyzer); ]]> addFilter($shortWordsFilter); Zend_Search_Lucene_Analysis_Analyzer::setDefault($analyzer); ]]> O construtor Zend_Search_Lucene_Analysis_TokenFilter_StopWords recebe uma matriz de stop-words como uma entrada. Mas as stop-words podem também ser carregadas a partir de um arquivo: loadFromFile($my_stopwords_file); $analyzer = new Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum_CaseInsensitive(); $analyzer->addFilter($stopWordsFilter); Zend_Search_Lucene_Analysis_Analyzer::setDefault($analyzer); ]]> Este arquivo deve ser um arquivo de texto comum com uma palavra em cada linha. O caractere '#' marca uma linha como um comentário. O construtor Zend_Search_Lucene_Analysis_TokenFilter_ShortWords é um argumento opcional. Este é o limite do comprimento de palavra, definido por padrão para 2. Algoritmos de Pontuação A pontuação de um documento d para uma consulta q é definida como segue: score(q,d) = sum( tf(t in d) * idf(t) * getBoost(t.field in d) * lengthNorm(t.field in d) ) * coord(q,d) * queryNorm(q) tf(t in d) - Zend_Search_Lucene_Search_Similarity::tf($freq) - um fator de pontuação baseado na frequência de um termo ou frase em um documento. idf(t) - Zend_Search_Lucene_Search_Similarity::idf($input, $reader) - um fator de pontuação para um termo simples com o índice especificado. getBoost(t.field in d) - o fator de reforço para o campo. lengthNorm($term) - O valor de normalização para um campo, dado o número total de termos contido nele. Este valor é armazenado junto com o índice. Estes valores, juntamente com os campos de reforço, são armazenados em um índice e multiplicados nas pontuações de acerto em cada campo, pelo código de busca. Comparações em campos longos são menos precisas, e implementações deste método usualmente retornam valores pequenos quando o número de "tokens" é grande, e valores grandes quando o número de "tokens" for pequeno. coord(q,d) - Zend_Search_Lucene_Search_Similarity::coord($overlap, $maxOverlap) - um fator de pontuação baseado no quociente de todos os termos de busca que um documento contém. A existência de uma grande quantidade de termos de busca indica um grau maior de comparação. As implementações deste método usualmente retornam valores significativos quando a razão entre estes parâmetros é grande e vice versa. queryNorm(q) - o valor de normalização para uma consulta dado a soma das relevâncias ao quadrado de cada termo da consulta. Este valor é então multiplicado pela relevância de cada item da consulta. Isto não afeta a pontuação, mas a quantidade de tentativas para gerar pontuações em comparações entre consultas. O algoritmo de pontuação pode ser customizado pela implementação da sua própria classe de similaridade. Para isso crie uma classe descendente de Zend_Search_Lucene_Search_Similarity como mostrado abaixo, então use o método Zend_Search_Lucene_Search_Similarity::setDefault($similarity); para defini-la como padrão. Recipientes de Armazenagem A classe abstrata Zend_Search_Lucene_Storage_Directory define a funcionalidade de diretório. O construtor do Zend_Search_Lucene usa como entrada uma string ou um objeto da classe Zend_Search_Lucene_Storage_Directory. A classe Zend_Search_Lucene_Storage_Directory_Filesystem implementa a funcionalidade de diretório para o sistema de arquivos. Se uma string for usada como entrada para o construtor do Zend_Search_Lucene, então o leitor do índice (um objeto Zend_Search_Lucene) a tratará como um caminho para o sistema de arquivos e instanciará um objeto Zend_Search_Lucene_Storage_Directory_Filesystem. Você pode definir a sua própria implementação de diretório estendendo a classe Zend_Search_Lucene_Storage_Directory. Métodos de Zend_Search_Lucene_Storage_Directory: O método getFileObject($filename) de uma instância Zend_Search_Lucene_Storage_Directory retorna um objeto Zend_Search_Lucene_Storage_File. A classe abstrata Zend_Search_Lucene_Storage_File implementa a abstração de arquivo e as primitivas de leitura de arquivos de índice. Se fizer isso, você também terá que estender Zend_Search_Lucene_Storage_File para a sua implementação de diretório. Somente dois métodos de Zend_Search_Lucene_Storage_File devem ser substituídos em sua implementação: