2009-10-07 19 views
15

Tengo dos conjuntos de índices de búsqueda. TestIndex (utilizado en nuestro entorno de prueba) y ProdIndex (utilizado en el entorno de PRODUCCIÓN). Consulta de búsqueda de Lucene: + fecha: [20090410184806 A 20091007184806] funciona bien para el índice de prueba pero da este mensaje de error para el índice de Prod.Ayuda necesaria para averiguar el motivo por el que maxClauseCount está configurado en error 1024

"maxClauseCount se establece en 1024"

Si ejecuto siguiente línea justo antes de ejecutar consulta de búsqueda, entonces no sale este error. BooleanQuery.SetMaxClauseCount (Int16.MaxValue); buscador. Búsqueda (myQuery, recopilador);

¿Me falta algo aquí? ¿Por qué no estoy obteniendo este error en el índice de prueba? El esquema para dos índices es el mismo.Sólo difieren wrt en el número de registros/datos.El índicePROD tiene mayor cantidad de registros (alrededor de 1300) que aquellos en la prueba uno (alrededor de 950).

Gracias por leer.

+0

chk http://wiki.apache.org/lucene-java/LuceneFAQ#Why_am_I_getting_a_TooManyClauses_exception.3F – Narayan

Respuesta

11

La consulta de rango esencialmente se transforma en una consulta booleana con una cláusula para cada valor posible, ORed juntos.

Por ejemplo, el precio + consulta: [10 a 13] se tranformed a una consulta booleana

+(price:10 price:11 price:12 price:13) 

asumiendo todos los valores de 10-13 existen en el índice.

Supongo que todos sus 1300 valores caen en el rango que ha dado. Entonces, la consulta booleana tiene 1300 cláusulas, que es más alta que el valor predeterminado de 1024. En el índice de prueba, no se alcanza el límite de 1024 ya que solo hay 950 valores.

+0

Gracias Shashikant para su answer.What es la solución para resolver este problema? BooleanQuery.SetMaxClauseCount (Int16.MaxValue); es supuestamente una llamada muy cara. Gracias. –

+1

La desventaja es el rendimiento de la consulta degrada con el recuento de marcas de tiempo únicas. Pero, no es tan malo. Puedes probarlo y verificar si la promoción es aceptable. En su mayoría deberías estar bien. Lucene 2.9 (Java) ha mejorado las consultas de rango dramáticamente. No estoy seguro de cuándo se transferirá a la versión .Net. Mientras tanto, hay otros trucos que puede usar para consultas de fecha. Por lo general, implica romper la fecha en año, mes y día.Esto necesita mucho trabajo para traducir la consulta del usuario al formato de lucene subyacente. Intenta buscar "consulta de fecha lucene" para obtener ideas interesantes. –

+0

Mientras tanto, puede diseñar su campo de fecha de manera diferente. ¿Podría restringirlo a días en un solo año? (lo que lo restringe a 365 valores)? ¿O divide los datos en año, mes y día y utiliza una consulta más compleja? Sé que esto no es elegante, pero puede funcionar. –

12

Tuve el mismo problema. Mi solución fue capturar BooleanQuery.TooManyClauses y dinámicamente aumentar maxClauseCount.

Aquí hay algunos códigos que son similares a los que tengo en producción.

buena suerte, Randy


    private static Hits searchIndex(Searcher searcher, Query query) 
     throws IOException 
    { 
     boolean retry = true; 
     while (retry) 
     { 
      try 
      { 
       retry = false; 
       Hits myHits = searcher.search(query); 
       return myHits; 
      } 
      catch (BooleanQuery.TooManyClauses e) 
      { 
       // Double the number of boolean queries allowed. 
       // The default is in org.apache.lucene.search.BooleanQuery and is 1024. 
       String defaultQueries = Integer.toString(BooleanQuery.getMaxClauseCount()); 
       int oldQueries = Integer.parseInt(System.getProperty("org.apache.lucene.maxClauseCount", defaultQueries)); 
       int newQueries = oldQueries * 2; 
       log.error("Too many hits for query: " + oldQueries + ". Increasing to " + newQueries, e); 
       System.setProperty("org.apache.lucene.maxClauseCount", Integer.toString(newQueries)); 
       BooleanQuery.setMaxClauseCount(newQueries); 
       retry = true; 
      } 
     } 
    } 
+0

Esta es una buena solución, pero ¿por qué no contar las cláusulas antes y luego configurarlas correctamente en lugar de después de atrapar la excepción? ¿Afectará esto el rendimiento si se procesa una gran cantidad de datos? – trillions

+1

Nanshi, la razón es porque * no * se puede calcular. No hay forma de averiguar cuántos elementos están incluidos en el rango hasta * después * de que realice una consulta, pero luego esa consulta se transforma en una consulta booleana donde se lanza la excepción. –

+0

¡Gracias, Randy! Tengo una diferencia en el caso de que construí consultas booleanas yo mismo, así que pude contarlas antes de ejecutar una búsqueda. – trillions

1

que tenía este mismo problema en C# código que se ejecuta con el sistema de gestión de contenidos web Sitecore. Utilicé la respuesta de Randy anteriormente, pero no pude usar el sistema Obtener y establecer la funcionalidad de la propiedad. En cambio, recuperé el recuento actual, lo incrementé y lo restablecí. Funcionó muy bien!

catch (BooleanQuery.TooManyClauses e) 
{ 
    // Increment the number of boolean queries allowed. 
    // The default is 1024. 
    var currMaxClause = BooleanQuery.GetMaxClauseCount(); 
    var newMaxClause = currMaxClause + 1024; 
    BooleanQuery.SetMaxClauseCount(newMaxClause); 
    retry = true; 
} 
0

Acaba de poner, BooleanQuery.setMaxClauseCount(Integer.MAX_VALUE); y eso es todo.

Cuestiones relacionadas