2008-08-12 14 views
7

He tenido una aplicación haciendo búsquedas de prefijo por un tiempo. Recientemente se aumentó el tamaño del índice y resultó que algunos prefijos eran demasiado numerosos para que lucene los manejara. Me siguió arrojando un error Too Many Clauses, lo cual fue muy frustrante ya que seguí mirando mis JAR y confirmando que ninguno de los códigos incluidos realmente usaba una consulta booleana.Con Lucene: ¿Por qué obtengo un error Demasiadas cláusulas si hago una búsqueda de prefijo?

¿Por qué no arrojar algo así como una excepción Too Many Hits? ¿Y por qué aumentar el entero estático de las cláusulas max de la consulta booleana hace desaparecer este error, cuando definitivamente solo estoy usando una consulta de prefijo? ¿Hay algo fundamental sobre cómo se ejecutan las consultas que no entiendo? ¿Es que secretamente se convierten en consultas booleanas?

Respuesta

5

He golpeado esto antes. Tiene que ver con el hecho de que Lucene, bajo las mantas, se convierte muchas cosas (todo?) En consultas booleanas cuando llame Query.rewrite()

Desde: http://lucene.apache.org/java/2_2_0/api/org/apache/lucene/search/Query.html#rewrite(org.apache.lucene.index.IndexReader)

public Query rewrite(IndexReader reader) 
       throws IOException 

    Expert: called to re-write queries into primitive queries. 
      For example, a PrefixQuery will be rewritten into a 
      BooleanQuery that consists of TermQuerys. 

    Throws: 
     IOException 
+1

Y esta 'Query.rewrite()' transformación * siempre * sucede antes de que la consulta se ejecute realmente? (Eso parece razonable, que la consulta debe desglosarse en consultas primitivas antes de ejecutarse). – KajMagnus

0

Cuando se ejecuta un prefijo consulta, Lucene busca todos los términos en su "diccionario" que coincidan con la consulta. Si coinciden más de 1024 (de forma predeterminada), se lanza TooManyClauses-Exception.

Puede llamar a BooleanQuery.setMaxClauseCount para aumentar el número máximo de cláusulas permitidas por BooleanQuery.

+0

Eso tiene sentido, pero el problema para mí fue que no tenía forma de saber que un PrefixQuery en realidad se convirtió en BooleanQuery. – dlamblin

3

La página de referencia de la API de TooManyClauses muestra que PrefixQuery, FuzzyQuery, WildcardQuery y RangeQuery se expanden de esta manera (en BooleanQuery). Dado que está en la referencia de API, debería ser un comportamiento en el que los usuarios puedan confiar. Lucene no impone límites arbitrarios al número de visitas (a excepción de que un ID de documento sea un int) por lo que una excepción de "demasiados aciertos" podría no tener sentido. Quizás PrefixQuery.rewrite (IndexReader) debería capturar TooManyClauses y lanzar una excepción de "demasiados prefijos", pero en este momento no se comporta de esa manera.

Por cierto, otra forma de buscar por prefijo es usar PrefixFilter. Filtre su consulta con ella o envuelva el filtro con una Constancia de búsqueda constante.

+0

¿'PrefixFilter' también se ha expandido a cláusulas booleanas? (¿O se implementa de manera diferente de alguna manera?) – KajMagnus

Cuestiones relacionadas