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: