12.3. Pesquisando em um Índice

12.3.1. Construindo Consultas

Existem duas maneiras de pesquisar o índice. O primeiro método usa um analisador de consultas para construir a pesquisa a partir de uma string. O segundo oferece a possibilidade de criação de consultas customizadas através da API do Zend_Search_Lucene.

Antes de decidir utilizar o analisador de consultas considere o seguinte:

  1. Se você pretende primeiro gerar programaticamente a string de consulta para depois submetê-la ao analisador então você deve considerar cuidadosamente a possibilidade a criação de suas consultas diretamente pela API. Em outras palavras, o analisador foi projetado para trabalhar com entradas de texto fornecidas por seres humanos e não com entradas geradas por software.
  2. Campos não tokenizados funcionam melhor se adicionados diretamente às consultas, do que pela ação do analisador. Se o conteúdo de um campo é gerado pela aplicação, então deveria haver um cláusula de consulta para este campo. Um interpretador, que é utilizado pelo analisador de consultas, é projetado para converter entradas de texto provenientes de seres humanos para cláusulas de busca. Valores gerados por programas, tais como datas, palavras-chave, etc., deveriam ser consistentes o suficiente para não necessitar do interpretador.
  3. Em um formulário de busca, somente os campos designados para receber texto deveriam ser submentidos ao analisador de consultas. Todo o resto (datas, tokens, etc.), pode ser submetido diretamente através da API de consulta. Um campo contendo um conjunto de valores, que pode ser exibido como um menu de persiana (pull-down), não deveria ser incluído na string de busca (e consequentemente submetido ao analisador), mas classificado como uma cláusula de busca.

Ambas as formas empregam o mesmo método da API para pesquisar no índice:

<?php

require_once('Zend/Search/Lucene.php');

$index = new Zend_Search_Lucene('/data/my_index');

$index->find($query);

?>

O método Zend_Search_Lucene::find() determina o tipo de dado de entrada automaticamente e usa o analisador de consultas para construir um objeto Zend_Search_Lucene_Search_Query apropriado a partir da string.

It is important to note that find() IS case sensitive. By default, LuceneIndexCreation.jar normalizes all documents to lowercase. This can be turned off with a command line switch (type LuceneIndexCreation.jar with no arguments for help). The case of the text supplied to find() must match that of the index. If the index is normalized to lowercase, then all text supplied to find() must pass through strtolower(), or else it may not match.

É importante ressaltar que o método find()é sensivel à caixa. Por padrão, LuceneIndexCreation.jar normaliza todos os documentos para minúsculas. Isso pode ser desativado informando um parâmetro na linha de comando (tecle LuceneIndexCreation.jar sem argumentos para exibir a lista de opções). A caixa do texto passado a find()deve ser a mesma usada pelo índice. Se o índice foi normalizado para minúsculas, então o texto informado a find()deverá ser submetido antes a strtolower(), caso contrário ele poderá não ser comparado.

12.3.2. Resultados da Pesquisa

The search result is an array of Zend_Search_Lucene_Search_QueryHit objects. Each of these has two properties: $hit->document is a document number within the index and $hit->score is a score of the hit in a search result. Result is ordered by score (top scores come first).

O resultado da pesquisa é um array de objetos da classe Zend_Search_Lucene_Search_QueryHit. Cada um contendo duas propriedades: $hit->document é um número de documento no índice e $hit->score é a pontuação de acertos no resultado da busca. O resultado é ordenado pela pontuação em ordem decrescente.

O objeto Zend_Search_Lucene_Search_QueryHit também exibe cada campo do Zend_Search_Lucene_Document encontrado pela busca como uma propriedade do objeto ("hit"). No exemplo abaixo, um acerto é retornado e o documento correspondente possui dois campos: título e autor.

<?php

require_once('Zend/Search/Lucene.php');

$index = new Zend_Search_Lucene('/data/my_index');

$hits = $index->find($query);

foreach ($hits as $hit) {
    echo $hit->id;
    echo $hit->score;

    echo $hit->title;
    echo $hit->author;
}

?>

Opcionalmente, o objeto Zend_Search_Lucene_Document original pode ser retornado pelo objeto Zend_Search_Lucene_Search_QueryHit. Se você consegue recuperar partes indexadas do documento usando o método getDocument() no índice, o documento pode ser obtido pelo método getFieldValue():

<?php

require_once('Zend/Search/Lucene.php');

$index = new Zend_Search_Lucene('/data/my_index');

$hits = $index->find($query);
foreach ($hits as $hit) {
    // return Zend_Search_Lucene_Document object for this hit
    echo $document = $hit->getDocument();

    // return a Zend_Search_Lucene_Field object
    // from the Zend_Search_Lucene_Document
    echo $document->getField('title');

    // return the string value of the Zend_Search_Lucene_Field object
    echo $document->getFieldValue('title');

    // same as getFieldValue()
    echo $document->title;
}

?>

Os campos que estão contidos no objeto Zend_Search_Lucene_Document são determinados em tempo de indexação. Os campos do documento ou serão indexados ou indexador e armazenados no documento pela aplicação indexadora (por exemplo: LuceneIndexCreation.jar).

Pay attention, that document identity ('path' in our example) is also stored in the index and must be retrieved from them.

Note que a identidade do documento ("path" em nosso exemplo) também será armazenado no índice e deverá ser recuperado a partir do mesmo.

12.3.3. Pontuação dos Resultados

O módulo Zend_Search_Lucene emprega o mesmo algoritmo de pontuação adotado pelo Java Lucene. Os resultados da busca são ordenados pela respectiva pontuação em ordem decrescente.

Em dois documentos com pontuações distintas, o que recebeu a maior pontuação contém mais termos que atendem aos requisitos da consulta do que o de pontuação menor.

Simplificando: Pontuações maiores indicam uma frequência maior de acertos ou frases.

A pontuação pode ser recuperada pela propriedade score do objeto "hit":

<?php
$hits = $index->find($query);

foreach ($hits as $hit) {
    echo $hit->id;
    echo $hit->score;
}

?>

A classe Zend_Search_Lucene_Search_Similarity é usada para calcular a pontuação. Consulte a seção Extensibilidade. Algoritmos de Pontuação para mais detalhes.