Además de analizar una consulta en forma de cadena automáticamente, también es posible construirlas con la API de consultas.
Las consultas de usuario pueden combinarse con consultas creadas a través de la API de consultas. Simplemente use el analizador de consultas para construir una consulta a partir de una cadena:
$query = Zend_Search_Lucene_Search_QueryParser::parse($queryString);
El analizador de consultas puede generar dos tipos de excepciones:
Zend_Search_Lucene_Exceptionse lanza si algo sale mal en el propio analizador de consultas.Zend_Search_Lucene_Search_QueryParserExceptionse lanza cuando hay un error en la sintaxis de la consulta.
Es una buena idea capturar
las excepciones Zend_Search_Lucene_Search_QueryParserException y manejarlas
apropiadamente:
try {
$query = Zend_Search_Lucene_Search_QueryParser::parse($queryString);
} catch (Zend_Search_Lucene_Search_QueryParserException $e) {
echo "Query syntax error: " . $e->getMessage() . "\n";
}
Se debe usar la misma técnica para el método find() de un objeto
Zend_Search_Lucene.
A partir de la versión 1.5, las excepciones de análisis de consultas se suprimen por defecto. Si la consulta no
se ajusta al lenguaje de consultas, entonces se tokeniza usando el analizador predeterminado actual y todos
los términos tokenizados se usan para la búsqueda. Use el método
Zend_Search_Lucene_Search_QueryParser::dontSuppressQueryParsingExceptions()
para activar las excepciones.
Los métodos
Zend_Search_Lucene_Search_QueryParser::suppressQueryParsingExceptions()
y
Zend_Search_Lucene_Search_QueryParser::queryParsingExceptionsSuppressed()
también están destinados a gestionar el comportamiento del manejo de excepciones.
Las consultas de término se pueden usar para buscar con un único término.
Cadena de consulta:
word1
o
Construcción de la consulta mediante la API:
$term = new Zend_Search_Lucene_Index_Term('word1', 'field1');
$query = new Zend_Search_Lucene_Search_Query_Term($term);
$hits = $index->find($query);
El campo del término es opcional. Zend_Search_Lucene busca en
todos los campos indexados de cada documento si no se especifica el campo:
// Search for 'word1' in all indexed fields
$term = new Zend_Search_Lucene_Index_Term('word1');
$query = new Zend_Search_Lucene_Search_Query_Term($term);
$hits = $index->find($query);
Las consultas multi-término se pueden usar para buscar con un conjunto de términos.
Cada término de un conjunto puede definirse como requerido, prohibido, o ninguno de los dos.
requerido significa que los documentos que no coincidan con este término no coincidirán con la consulta;
prohibido significa que los documentos que coincidan con este término no coincidirán con la consulta;
ninguno de los dos, en cuyo caso los documentos coincidentes no están ni prohibidos ni obligados a coincidir con el término. Un documento debe coincidir con al menos 1 término, sin embargo, para coincidir con la consulta.
Si se añaden términos opcionales a una consulta con términos requeridos, ambas consultas tendrán el mismo conjunto de resultados, pero los términos opcionales pueden afectar la puntuación de los documentos coincidentes.
Ambos métodos de búsqueda se pueden usar para consultas multi-término.
Cadena de consulta:
+word1 author:word2 -word3
'+' se usa para definir un término requerido.
'-' se usa para definir un término prohibido.
El prefijo 'field:' se usa para indicar un campo del documento para una búsqueda. Si se omite, entonces se buscan todos los campos.
o
Construcción de la consulta mediante la API:
$query = new Zend_Search_Lucene_Search_Query_MultiTerm();
$query->addTerm(new Zend_Search_Lucene_Index_Term('word1'), true);
$query->addTerm(new Zend_Search_Lucene_Index_Term('word2', 'author'),
null);
$query->addTerm(new Zend_Search_Lucene_Index_Term('word3'), false);
$hits = $index->find($query);
También es posible especificar una lista de términos dentro del constructor de la consulta MultiTerm:
$terms = array(new Zend_Search_Lucene_Index_Term('word1'),
new Zend_Search_Lucene_Index_Term('word2', 'author'),
new Zend_Search_Lucene_Index_Term('word3'));
$signs = array(true, null, false);
$query = new Zend_Search_Lucene_Search_Query_MultiTerm($terms, $signs);
$hits = $index->find($query);
El array $signs contiene información sobre el tipo de término:
TRUEse usa para definir un término requerido.FALSEse usa para definir un término prohibido.NULLse usa para definir un término que no es ni requerido ni prohibido.
Las consultas booleanas permiten construir una consulta usando otras consultas y operadores booleanos.
Cada subconsulta de un conjunto puede definirse como requerida, prohibida, o opcional.
requerida significa que los documentos que no coincidan con esta subconsulta no coincidirán con la consulta;
prohibida significa que los documentos que coincidan con esta subconsulta no coincidirán con la consulta;
opcional, en cuyo caso los documentos coincidentes no están ni prohibidos ni obligados a coincidir con la subconsulta. Un documento debe coincidir con al menos 1 subconsulta, sin embargo, para coincidir con la consulta.
Si se añaden subconsultas opcionales a una consulta con subconsultas requeridas, ambas consultas tendrán el mismo conjunto de resultados, pero las subconsultas opcionales pueden afectar la puntuación de los documentos coincidentes.
Ambos métodos de búsqueda se pueden usar para consultas booleanas.
Cadena de consulta:
+(word1 word2 word3) (author:word4 author:word5) -(word6)
'+' se usa para definir una subconsulta requerida.
'-' se usa para definir una subconsulta prohibida.
El prefijo 'field:' se usa para indicar un campo del documento para una búsqueda. Si se omite, entonces se buscan todos los campos.
o
Construcción de la consulta mediante la API:
$query = new Zend_Search_Lucene_Search_Query_Boolean();
$subquery1 = new Zend_Search_Lucene_Search_Query_MultiTerm();
$subquery1->addTerm(new Zend_Search_Lucene_Index_Term('word1'));
$subquery1->addTerm(new Zend_Search_Lucene_Index_Term('word2'));
$subquery1->addTerm(new Zend_Search_Lucene_Index_Term('word3'));
$subquery2 = new Zend_Search_Lucene_Search_Query_MultiTerm();
$subquery2->addTerm(new Zend_Search_Lucene_Index_Term('word4', 'author'));
$subquery2->addTerm(new Zend_Search_Lucene_Index_Term('word5', 'author'));
$term6 = new Zend_Search_Lucene_Index_Term('word6');
$subquery3 = new Zend_Search_Lucene_Search_Query_Term($term6);
$query->addSubquery($subquery1, true /* required */);
$query->addSubquery($subquery2, null /* optional */);
$query->addSubquery($subquery3, false /* prohibited */);
$hits = $index->find($query);
También es posible especificar una lista de subconsultas dentro del constructor de la consulta Boolean:
... $subqueries = array($subquery1, $subquery2, $subquery3); $signs = array(true, null, false); $query = new Zend_Search_Lucene_Search_Query_Boolean($subqueries, $signs); $hits = $index->find($query);
El array $signs contiene información sobre el tipo de subconsulta:
TRUEse usa para definir una subconsulta requerida.FALSEse usa para definir una subconsulta prohibida.NULLse usa para definir una subconsulta que no es ni requerida ni prohibida.
Toda consulta que use operadores booleanos puede reescribirse usando la notación de signos y construirse usando la API. Por ejemplo:
word1 AND (word2 AND word3 AND NOT word4) OR word5
es equivalente a
(+(word1) +(+word2 +word3 -word4)) (word5)
Las consultas de comodín se pueden usar para buscar documentos que contengan cadenas que coincidan con patrones especificados.
El símbolo '?' se usa como comodín de un solo carácter.
El símbolo '*' se usa como comodín de varios caracteres.
Cadena de consulta:
field1:test*
o
Construcción de la consulta mediante la API:
$pattern = new Zend_Search_Lucene_Index_Term('test*', 'field1');
$query = new Zend_Search_Lucene_Search_Query_Wildcard($pattern);
$hits = $index->find($query);
El campo del término es opcional. Zend_Search_Lucene busca en
todos los campos de cada documento si no se especifica un campo:
$pattern = new Zend_Search_Lucene_Index_Term('test*');
$query = new Zend_Search_Lucene_Search_Query_Wildcard($pattern);
$hits = $index->find($query);
Las consultas difusas se pueden usar para buscar documentos que contengan cadenas que coincidan con términos similares al término especificado.
Cadena de consulta:
field1:test~
Esta consulta coincide con documentos que contienen las palabras 'test', 'text', 'best' y otras.
o
Construcción de la consulta mediante la API:
$term = new Zend_Search_Lucene_Index_Term('test', 'field1');
$query = new Zend_Search_Lucene_Search_Query_Fuzzy($term);
$hits = $index->find($query);
Se puede especificar una similitud opcional después del signo "~".
Cadena de consulta:
field1:test~0.4
o
Construcción de la consulta mediante la API:
$term = new Zend_Search_Lucene_Index_Term('test', 'field1');
$query = new Zend_Search_Lucene_Search_Query_Fuzzy($term, 0.4);
$hits = $index->find($query);
El campo del término es opcional. Zend_Search_Lucene busca en
todos los campos de cada documento si no se especifica un campo:
$term = new Zend_Search_Lucene_Index_Term('test');
$query = new Zend_Search_Lucene_Search_Query_Fuzzy($term);
$hits = $index->find($query);
Las consultas de frase se pueden usar para buscar una frase dentro de los documentos.
Las consultas de frase son muy flexibles y permiten al usuario o desarrollador buscar frases exactas así como frases 'imprecisas'.
Las frases también pueden contener huecos o términos en las mismas posiciones; pueden ser generados por el analizador para diferentes propósitos. Por ejemplo, un término puede duplicarse para aumentar su peso, o se pueden colocar varios sinónimos en una única posición.
$query1 = new Zend_Search_Lucene_Search_Query_Phrase();
// Add 'word1' at 0 relative position.
$query1->addTerm(new Zend_Search_Lucene_Index_Term('word1'));
// Add 'word2' at 1 relative position.
$query1->addTerm(new Zend_Search_Lucene_Index_Term('word2'));
// Add 'word3' at 3 relative position.
$query1->addTerm(new Zend_Search_Lucene_Index_Term('word3'), 3);
...
$query2 = new Zend_Search_Lucene_Search_Query_Phrase(
array('word1', 'word2', 'word3'), array(0,1,3));
...
// Query without a gap.
$query3 = new Zend_Search_Lucene_Search_Query_Phrase(
array('word1', 'word2', 'word3'));
...
$query4 = new Zend_Search_Lucene_Search_Query_Phrase(
array('word1', 'word2'), array(0,1), 'annotation');
Una consulta de frase puede construirse en un solo paso con un constructor de clase o paso a paso
con llamadas al método Zend_Search_Lucene_Search_Query_Phrase::addTerm().
El constructor de la clase Zend_Search_Lucene_Search_Query_Phrase toma
tres argumentos opcionales:
Zend_Search_Lucene_Search_Query_Phrase(
[array $terms[, array $offsets[, string $field]]]
);
El parámetro $terms es un array de cadenas que contiene un conjunto de
términos de la frase. Si se omite o es igual a NULL, entonces se construye una
consulta vacía.
El parámetro $offsets es un array de enteros que contiene los desplazamientos
de los términos en una frase. Si se omite o es igual a NULL, entonces se
asume que las posiciones de los términos son secuenciales sin huecos.
El parámetro $field es una cadena que indica el campo del documento
a buscar. Si se omite o es igual a NULL, entonces se busca en el campo
predeterminado.
Así:
$query =
new Zend_Search_Lucene_Search_Query_Phrase(array('zend', 'framework'));
buscará la frase 'zend framework' en todos los campos.
$query = new Zend_Search_Lucene_Search_Query_Phrase(
array('zend', 'download'), array(0, 2)
);
buscará la frase 'zend ????? download' y coincidirá con 'zend platform download', 'zend studio download', 'zend core download', 'zend framework download', etcétera.
$query = new Zend_Search_Lucene_Search_Query_Phrase(
array('zend', 'framework'), null, 'title'
);
buscará la frase 'zend framework' en el campo 'title'.
Zend_Search_Lucene_Search_Query_Phrase::addTerm() toma dos
argumentos, un objeto Zend_Search_Lucene_Index_Term requerido y una
posición opcional:
Zend_Search_Lucene_Search_Query_Phrase::addTerm(
Zend_Search_Lucene_Index_Term $term[, integer $position]
);
El parámetro $term describe el siguiente término en la frase. Debe
indicar el mismo campo que los términos anteriores, o se lanzará una excepción.
El parámetro $position indica la posición del término en la frase.
Así:
$query = new Zend_Search_Lucene_Search_Query_Phrase();
$query->addTerm(new Zend_Search_Lucene_Index_Term('zend'));
$query->addTerm(new Zend_Search_Lucene_Index_Term('framework'));
buscará la frase 'zend framework'.
$query = new Zend_Search_Lucene_Search_Query_Phrase();
$query->addTerm(new Zend_Search_Lucene_Index_Term('zend'), 0);
$query->addTerm(new Zend_Search_Lucene_Index_Term('framework'), 2);
buscará la frase 'zend ????? download' y coincidirá con 'zend platform download', 'zend studio download', 'zend core download', 'zend framework download', etcétera.
$query = new Zend_Search_Lucene_Search_Query_Phrase();
$query->addTerm(new Zend_Search_Lucene_Index_Term('zend', 'title'));
$query->addTerm(new Zend_Search_Lucene_Index_Term('framework', 'title'));
buscará la frase 'zend framework' en el campo 'title'.
El factor de holgura (slop) establece el número de otras palabras permitidas entre las palabras especificadas en la frase de consulta. Si se establece en cero, entonces la consulta correspondiente es una búsqueda de frase exacta. Para valores mayores esto funciona como los operadores WITHIN o NEAR.
El factor de holgura es en realidad una distancia de edición, donde las ediciones corresponden a mover términos en la frase de consulta. Por ejemplo, para intercambiar el orden de dos palabras se requieren dos movimientos (el primer movimiento coloca las palabras una encima de la otra), así que para permitir reordenaciones de frases, el factor de holgura debe ser de al menos dos.
Las coincidencias más exactas obtienen una puntuación más alta que las coincidencias menos exactas; por lo tanto, los resultados de búsqueda se ordenan por exactitud. La holgura es cero por defecto, requiriendo coincidencias exactas.
El factor de holgura se puede asignar después de la creación de la consulta:
// Query without a gap.
$query =
new Zend_Search_Lucene_Search_Query_Phrase(array('word1', 'word2'));
// Search for 'word1 word2', 'word1 ... word2'
$query->setSlop(1);
$hits1 = $index->find($query);
// Search for 'word1 word2', 'word1 ... word2',
// 'word1 ... ... word2', 'word2 word1'
$query->setSlop(2);
$hits2 = $index->find($query);
Las consultas de rango están destinadas a buscar términos dentro de un intervalo especificado.
Cadena de consulta:
mod_date:[20020101 TO 20030101]
title:{Aida TO Carmen}
o
Construcción de la consulta mediante la API:
$from = new Zend_Search_Lucene_Index_Term('20020101', 'mod_date');
$to = new Zend_Search_Lucene_Index_Term('20030101', 'mod_date');
$query = new Zend_Search_Lucene_Search_Query_Range(
$from, $to, true // inclusive
);
$hits = $index->find($query);
Los campos de término son opcionales. Zend_Search_Lucene busca en todos los
campos si no se especifica el campo:
$from = new Zend_Search_Lucene_Index_Term('Aida');
$to = new Zend_Search_Lucene_Index_Term('Carmen');
$query = new Zend_Search_Lucene_Search_Query_Range(
$from, $to, false // non-inclusive
);
$hits = $index->find($query);
Cualquiera (pero no ambos) de los términos límite puede establecerse en NULL.
Zend_Search_Lucene busca desde el principio o
hasta el final del diccionario para los campos especificados en este caso:
// searches for ['20020101' TO ...]
$from = new Zend_Search_Lucene_Index_Term('20020101', 'mod_date');
$query = new Zend_Search_Lucene_Search_Query_Range(
$from, null, true // inclusive
);
$hits = $index->find($query);