Hay dos formas de buscar en el índice. El primer método utiliza
el analizador de consultas para construir una consulta a partir de una cadena. El segundo consiste
en crear sus propias consultas de forma programática a través de la
API de Zend_Search_Lucene.
Antes de decidir usar el analizador de consultas proporcionado, considere lo siguiente:
Si está creando una cadena de consulta de forma programática y luego la analiza con el analizador de consultas, debería considerar construir sus consultas directamente con la API de consultas. En términos generales, el analizador de consultas está diseñado para texto introducido por personas, no para texto generado por programas.
Los campos no tokenizados se agregan mejor directamente a las consultas y no a través del analizador de consultas. Si los valores de un campo son generados de forma programática por la aplicación, entonces las cláusulas de consulta para ese campo también deberían construirse de forma programática. Un analizador, que es utilizado por el analizador de consultas, está diseñado para convertir texto introducido por personas en términos. Los valores generados por programas, como fechas, palabras clave, etc., deberían agregarse con la API de consultas.
En un formulario de consulta, los campos que son texto general deberían usar el analizador de consultas. Todos los demás, como rangos de fechas, palabras clave, etc., se agregan mejor directamente a través de la API de consultas. Un campo con un conjunto limitado de valores que pueda especificarse mediante un menú desplegable no debería agregarse a una cadena de consulta que se analice posteriormente, sino que debería agregarse como una cláusula TermQuery.
Las consultas booleanas permiten al programador combinar lógicamente dos o más consultas en una nueva. Por lo tanto, es la mejor forma de agregar criterios adicionales a una búsqueda definida por una cadena de consulta.
Ambas formas usan el mismo método de la API para buscar en el índice:
$index = Zend_Search_Lucene::open('/data/my_index');
$index->find($query);
También puede buscar en varios índices simultáneamente usando MultiSearcher, que funciona usando la misma API que la búsqueda en un solo índice:
$multi = new Zend_Search_Lucene_MultiSearcher();
$multi->addIndex(Zend_Search_Lucene::open('/data/my_index_one');
$multi->addIndex(Zend_Search_Lucene::open('/data/my_index_two');
$multi->find($query);
El método Zend_Search_Lucene::find() determina el tipo de entrada
automáticamente y utiliza el analizador de consultas para construir un objeto
Zend_Search_Lucene_Search_Query adecuado a partir de una entrada de tipo
string.
Es importante señalar que el analizador de consultas utiliza el analizador estándar para tokenizar partes separadas de la cadena de consulta. Por lo tanto, todas las transformaciones que se aplican al texto indexado también se aplican a las cadenas de consulta.
El analizador estándar puede transformar la cadena de consulta a minúsculas para insensibilidad a mayúsculas y minúsculas, eliminar palabras vacías, y aplicar stemming, entre otras transformaciones.
El método de la API no transforma ni filtra los términos de entrada de ninguna forma. Por lo tanto, es más adecuado para campos generados por computadora o no tokenizados.
El método Zend_Search_Lucene_Search_QueryParser::parse() puede
usarse para analizar cadenas de consulta y convertirlas en objetos de consulta.
Este objeto de consulta puede usarse en los métodos de la API de construcción de consultas para combinar consultas introducidas por el usuario con consultas generadas de forma programática.
De hecho, en algunos casos es la única forma de buscar valores dentro de campos no tokenizados:
$userQuery = Zend_Search_Lucene_Search_QueryParser::parse($queryStr);
$pathTerm = new Zend_Search_Lucene_Index_Term(
'/data/doc_dir/' . $filename, 'path'
);
$pathQuery = new Zend_Search_Lucene_Search_Query_Term($pathTerm);
$query = new Zend_Search_Lucene_Search_Query_Boolean();
$query->addSubquery($userQuery, true /* required */);
$query->addSubquery($pathQuery, true /* required */);
$hits = $index->find($query);
El método Zend_Search_Lucene_Search_QueryParser::parse() también
acepta un parámetro opcional de codificación, que puede especificar la codificación de la cadena de consulta:
$userQuery = Zend_Search_Lucene_Search_QueryParser::parse($queryStr,
'iso-8859-5');
Si se omite el parámetro de codificación, se utiliza la configuración regional actual.
También es posible especificar la codificación de cadena de consulta predeterminada con el método
Zend_Search_Lucene_Search_QueryParser::setDefaultEncoding():
Zend_Search_Lucene_Search_QueryParser::setDefaultEncoding('iso-8859-5');
...
$userQuery = Zend_Search_Lucene_Search_QueryParser::parse($queryStr);
Zend_Search_Lucene_Search_QueryParser::getDefaultEncoding()
devuelve la codificación de cadena de consulta predeterminada actual (la cadena vacía significa "configuración regional
actual").
El resultado de la búsqueda es un array de objetos
Zend_Search_Lucene_Search_QueryHit. Cada uno de estos tiene dos
propiedades: $hit->id es un número de documento dentro del índice y
$hit->score es la puntuación del resultado en un resultado de búsqueda. Los resultados están
ordenados por puntuación (descendente desde la puntuación más alta).
El objeto Zend_Search_Lucene_Search_QueryHit también expone cada
campo del Zend_Search_Lucene_Document encontrado en la búsqueda como una
propiedad del resultado. En el siguiente ejemplo, se devuelve un resultado con dos campos del
documento correspondiente: title y author.
$index = Zend_Search_Lucene::open('/data/my_index');
$hits = $index->find($query);
foreach ($hits as $hit) {
echo $hit->score;
echo $hit->title;
echo $hit->author;
}
Los campos almacenados siempre se devuelven en codificación UTF-8.
Opcionalmente, el objeto original Zend_Search_Lucene_Document puede
devolverse desde el Zend_Search_Lucene_Search_QueryHit.
Puede recuperar las partes almacenadas del documento usando el método
getDocument() del objeto índice y luego obtenerlas mediante el
método getFieldValue():
$index = Zend_Search_Lucene::open('/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;
}
Los campos disponibles desde el objeto Zend_Search_Lucene_Document
se determinan en el momento de la indexación. Los campos del documento están indexados, o
indexados y almacenados, en el documento por la aplicación de indexación
(por ejemplo, LuceneIndexCreation.jar).
Tenga en cuenta que la identidad del documento ('path' en nuestro ejemplo) también se almacena en el índice y debe recuperarse de él.
La parte más costosa computacionalmente de la búsqueda es el cálculo de la puntuación. Puede tardar varios segundos para conjuntos de resultados grandes (decenas de miles de resultados).
Zend_Search_Lucene ofrece la posibilidad de limitar el tamaño del conjunto de resultados
con los métodos getResultSetLimit() y
setResultSetLimit():
$currentResultSetLimit = Zend_Search_Lucene::getResultSetLimit(); Zend_Search_Lucene::setResultSetLimit($newLimit);
El valor predeterminado de 0 significa 'sin límite'.
No proporciona los 'mejores N' resultados, sino solo los 'primeros N' [11].
Zend_Search_Lucene utiliza los mismos algoritmos de puntuación que Java
Lucene. Todos los resultados en el resultado de búsqueda se ordenan por puntuación de forma predeterminada. Los resultados con mayor
puntuación aparecen primero, y los documentos con puntuaciones más altas deberían coincidir con la consulta con más
precisión que los documentos con puntuaciones más bajas.
En términos generales, los resultados de búsqueda que contienen el término o frase buscada con más frecuencia tendrán una puntuación más alta.
La puntuación de un resultado puede recuperarse accediendo a la propiedad score del resultado:
$hits = $index->find($query);
foreach ($hits as $hit) {
echo $hit->id;
echo $hit->score;
}
La clase Zend_Search_Lucene_Search_Similarity se utiliza para
calcular la puntuación de cada resultado. Consulte la sección Extensibilidad. Algoritmos
de puntuación para más detalles.
De forma predeterminada, los resultados de búsqueda se ordenan por puntuación. El programador puede cambiar este comportamiento estableciendo un campo de ordenación (o una lista de campos), tipo de ordenación y orden de ordenación como parámetros.
La llamada a $index->find() puede aceptar varios parámetros opcionales:
$index->find($query [, $sortField [, $sortType [, $sortOrder]]]
[, $sortField2 [, $sortType [, $sortOrder]]]
...);
Un nombre de campo almacenado por el cual ordenar el resultado debe pasarse como el
parámetro $sortField.
$sortType puede omitirse o tomar los siguientes valores enumerados:
SORT_REGULAR (comparar los elementos normalmente, valor predeterminado),
SORT_NUMERIC (comparar los elementos numéricamente),
SORT_STRING (comparar los elementos como cadenas).
$sortOrder puede omitirse o tomar los siguientes valores enumerados:
SORT_ASC (ordenar en orden ascendente, valor predeterminado),
SORT_DESC (ordenar en orden descendente).
Ejemplos:
$index->find($query, 'quantity', SORT_NUMERIC, SORT_DESC);
$index->find($query, 'fname', SORT_STRING, 'lname', SORT_STRING);
$index->find($query, 'name', SORT_STRING, 'quantity', SORT_NUMERIC, SORT_DESC);
Utilice con precaución un orden de búsqueda que no sea el predeterminado; la consulta necesita recuperar documentos completamente desde un índice, lo que puede reducir drásticamente el rendimiento de la búsqueda.
Zend_Search_Lucene ofrece dos opciones para el resaltado de
resultados de búsqueda.
La primera consiste en utilizar la clase Zend_Search_Lucene_Document_Html
(consulte la sección Documentos
HTML para más detalles) usando los siguientes métodos:
/** * Highlight text with specified color * * @param string|array $words * @param string $colour * @return string */ public function highlight($words, $colour = '#66ffff');
/**
* Highlight text using specified View helper or callback function.
*
* @param string|array $words Words to highlight. Words could be organized
using the array or string.
* @param callback $callback Callback method, used to transform
(highlighting) text.
* @param array $params Array of additionall callback parameters passed
through into it (first non-optional parameter
is an HTML fragment for highlighting)
* @return string
* @throws Zend_Search_Lucene_Exception
*/
public function highlightExtended($words, $callback, $params = array())
Para personalizar el comportamiento del resaltado use el método highlightExtended()
con una devolución de llamada específica, que acepta uno o más parámetros
[12]
, o extienda la clase Zend_Search_Lucene_Document_Html y redefina
el método applyColour($stringToHighlight, $colour) usado como
función de resaltado predeterminada.
[13]
Los ayudantes de vista también pueden usarse como devoluciones de llamada en el contexto de un script de vista:
$doc->highlightExtended('word1 word2 word3...', array($this, 'myViewHelper'));
El resultado de la operación de resaltado se obtiene mediante el método
Zend_Search_Lucene_Document_Html->getHTML().
![]() |
Nota |
|---|---|
|
El resaltado se realiza en función del analizador actual. Por lo tanto, se resaltan todas las formas de la(s) palabra(s) reconocidas por el analizador. Por ejemplo, si el analizador actual no distingue entre mayúsculas y minúsculas y solicitamos resaltar la palabra 'text', entonces se resaltarán 'text', 'Text', 'TEXT' y otras combinaciones de mayúsculas y minúsculas. De la misma forma, si el analizador actual admite stemming y solicitamos resaltar 'indexed', entonces se resaltarán 'index', 'indexing', 'indices' y otras formas de la palabra. Por otro lado, si una palabra es omitida por el analizador actual (por ejemplo, si se aplica un filtro de palabras cortas al analizador), entonces no se resaltará nada. |
La segunda opción es usar el método
Zend_Search_Lucene_Search_Query->highlightMatches(string $inputHTML[,
$defaultEncoding = 'UTF-8'[,
Zend_Search_Lucene_Search_Highlighter_Interface $highlighter]]):
$query = Zend_Search_Lucene_Search_QueryParser::parse($queryStr); $highlightedHTML = $query->highlightMatches($sourceHTML);
El segundo parámetro opcional es una codificación de documento HTML predeterminada. Se utiliza si no se especifica la codificación mediante la etiqueta meta HTTP-EQUIV Content-type.
El tercer parámetro opcional es un objeto resaltador que debe implementar la interfaz
Zend_Search_Lucene_Search_Highlighter_Interface:
interface Zend_Search_Lucene_Search_Highlighter_Interface
{
/**
* Set document for highlighting.
*
* @param Zend_Search_Lucene_Document_Html $document
*/
public function setDocument(Zend_Search_Lucene_Document_Html $document);
/**
* Get document for highlighting.
*
* @return Zend_Search_Lucene_Document_Html $document
*/
public function getDocument();
/**
* Highlight specified words (method is invoked once per subquery)
*
* @param string|array $words Words to highlight. They could be
organized using the array or string.
*/
public function highlight($words);
}
Donde el objeto Zend_Search_Lucene_Document_Html es un objeto
construido a partir del HTML de origen proporcionado al
método Zend_Search_Lucene_Search_Query->highlightMatches().
Si se omite el parámetro $highlighter, entonces se
instancia y utiliza un objeto Zend_Search_Lucene_Search_Highlighter_Default.
El método highlight() del resaltador se invoca una vez por subconsulta, por lo que
tiene la capacidad de diferenciar el resaltado entre ellas.
De hecho, el resaltador predeterminado hace esto recorriendo una tabla de colores predefinida. Por lo tanto puede implementar su propio resaltador o simplemente extender el predeterminado y redefinir la tabla de colores.
Zend_Search_Lucene_Search_Query->htmlFragmentHighlightMatches() tiene un comportamiento similar.
La única diferencia es que recibe como entrada y devuelve un fragmento
HTML sin las etiquetas <>HTML>, <HEAD>, <BODY>.
Sin embargo, el fragmento se transforma automáticamente en XHTML válido.
[11] Los resultados devueltos siguen ordenándose por puntuación o por el orden especificado, si se indicó alguno.
[12] El primero es un fragmento HTML para resaltar y los demás dependen del comportamiento de la devolución de llamada. El valor devuelto es un fragmento HTML resaltado.
[13] En ambos casos, el HTML devuelto se transforma automáticamente en XHTML válido.
![[Note]](images/note.png)