2008-08-12 15 views
7

J'ai une application qui fait des recherches de préfixes depuis un moment. Récemment, la taille de l'index a été augmentée et il s'est avéré que certains préfixes étaient trop nombreux pour Lucene à gérer. Il me renvoyait une erreur Too Many Clauses, ce qui était très frustrant car je continuais à regarder mes fichiers JAR et à confirmer qu'aucun code inclus n'utilisait une requête booléenne.Avec Lucene: Pourquoi ai-je une erreur Trop de Clauses si je fais une recherche de préfixe?

Pourquoi ne pas jeter quelque chose comme une exception Too Many Hits? Et pourquoi augmenter le nombre entier de clauses max statiques de la requête booléenne fait-il disparaître cette erreur, alors que je n'utilise définitivement qu'une requête de préfixe? Y a-t-il quelque chose de fondamental dans la façon dont les requêtes sont exécutées que je ne comprends pas? Est-ce qu'ils deviennent secrètement des requêtes booléennes?

Répondre

5

Je l'ai frappé auparavant. Il a à voir avec le fait que Lucene, sous les couvertures, se beaucoup (tout?) Les choses dans les requêtes booléennes lorsque vous appelez Query.rewrite()

De: 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

Et ce 'Query.rewrite()' transformation * toujours * se produit avant que la requête est effectivement exécutée? (Ce serait semble raisonnable, que la requête doit être décomposées aux requêtes primitives avant d'être exécuté.) – KajMagnus

0

Lors de l'exécution d'un préfixe requête, Lucene recherche tous les termes dans son "dictionnaire" qui correspondent à la requête. Si plus de 1024 (par défaut) correspondent, la TooManyClauses-Exception est levée.

Vous pouvez appeler BooleanQuery.setMaxClauseCount pour augmenter le nombre maximum de clauses autorisées par BooleanQuery.

+0

Cela est logique, mais la question pour moi est que j'avais aucun moyen de savoir un PrefixQuery est devenu en fait un BooleanQuery. – dlamblin

3

La page de référence API de TooManyClauses montre que PrefixQuery, FuzzyQuery, WildcardQuery et RangeQuery sont développés de cette manière (dans BooleanQuery). Comme il est dans la référence API, il devrait être un comportement sur lequel les utilisateurs peuvent compter. Lucene ne place pas de limites arbitraires sur le nombre de hits (autre qu'un ID de document étant un int), donc une exception "too much hits" peut ne pas avoir de sens. Peut-être que PrefixQuery.rewrite (IndexReader) devrait attraper les TooManyClauses et lancer une exception "too many prefixes", mais pour le moment il ne se comporte pas ainsi.

Par ailleurs, une autre façon de rechercher par le préfixe est d'utiliser PrefixFilter. Soit filtrez votre requête avec elle ou enveloppez le filtre avec un ConstantScoreQuery.

+0

Est-ce que 'PrefixFilter' est aussi développé en clauses booléennes? (Ou est-il mis en œuvre différemment d'une manière ou d'une autre?) – KajMagnus