c# - index - Luke Lucene BooleanQuery
lucene index (2)
QueryParser
tomará una consulta como "docurl: www.siteurl.com docfile: Tomatoes *" y creará una consulta adecuada (consulta booleana, consulta de rango, etc.) dependiendo de la consulta dada (consulte la sintaxis de la consulta ).
El primer paso debe ser adjuntar un depurador e inspeccionar el valor y el tipo de parsedQuery
.
En Luke, la siguiente expresión de búsqueda arroja 23 resultados:
docurl:www.siteurl.com docfile:Tomatoes*
Si paso esta misma expresión en mi aplicación C # Lucene.NET con la siguiente implementación:
IndexReader reader = IndexReader.Open(indexName);
Searcher searcher = new IndexSearcher(reader);
try
{
QueryParser parser = new QueryParser("docurl", new StandardAnalyzer());
BooleanQuery bquery = new BooleanQuery();
Query parsedQuery = parser.Parse(query);
bquery.Add(parsedQuery, Lucene.Net.Search.BooleanClause.Occur.MUST);
int _max = searcher.MaxDoc();
BooleanQuery.SetMaxClauseCount(Int32.MaxValue);
TopDocs hits = searcher.Search(parsedQuery, _max)
...
}
Obtengo 0 resultados
Luke está usando StandardAnalyzer y así es como se ve la ventana Explain Structure:
¿Debo crear manualmente objetos BooleanClause
para cada campo en el que realizo una búsqueda, especificando Should
para cada uno y luego agregarlos al objeto BooleanQuery
con .Add()
? Pensé que QueryParser
haría esto por mí. ¿Qué me estoy perdiendo?
Editar: Simplificando un poco, docfile:Tomatoes*
devuelve 23 documentos en Luke, pero 0 en mi aplicación. Según la sugerencia de Per Gene, he cambiado de MUST
a SHOULD
:
QueryParser parser = new QueryParser("docurl", new StandardAnalyzer());
BooleanQuery bquery = new BooleanQuery();
Query parsedQuery = parser.Parse(query);
bquery.Add(parsedQuery, Lucene.Net.Search.BooleanClause.Occur.SHOULD);
int _max = searcher.MaxDoc();
BooleanQuery.SetMaxClauseCount(Int32.MaxValue);
TopDocs hits = searcher.Search(parsedQuery, _max);
parsedQuery es simplemente docfile:tomatoes*
Edit2:
Creo que finalmente llegué al problema de raíz:
QueryParser parser = new QueryParser("docurl", new StandardAnalyzer());
Query parsedQuery = parser.Parse(query);
En la segunda línea, la query
es "docfile:Tomatoes*"
, pero parsedQuery
es {docfile:tomatoes*}
. Observe la diferencia? Minúscula ''t'' en la consulta analizada. Nunca me había dado cuenta de esto antes. Si cambio el valor en el IDE a ''T'', devuelven 23 resultados.
Comprobé que StandardAnalyzer
se está utilizando al indexar y leer el índice. ¿Cómo queryParser
para mantener el caso del valor de la query
?
Edit3: Wow, qué frustrante. De acuerdo con la documentación , puedo lograr esto con:
parser.setLowercaseExpandedTerms (falso);
Si los términos de las consultas de comodín, prefijo, difuso y de rango se deben incluir automáticamente o no. El valor predeterminado es verdadero
No discutiré si es un defecto sensato o no. Supongo que SimpleAnalyzer debería haberse usado para minúsculas dentro y fuera del índice. La parte frustrante es que, al menos con la versión que estoy usando, ¡Luke falla por otro lado! Al menos aprendí un poco más sobre Lucene.
Usar Occur.MUST
es equivalente a usar el operador +
con el analizador de consultas estándar. Por lo tanto, tu código está evaluando +docurl:www.siteurl.com +docfile:Tomatoes*
lugar de la expresión que escribiste en Luke. Para obtener ese comportamiento, pruebe Occur.SHOULD
cuando agregue sus cláusulas.