Domanda

Nei miei test mi sono imbattuto improvvisamente in un'eccezione Too Many Clauses quando ho cercato di ottenere gli hit da una query booleana che consisteva in una query termquery e una query jolly.

Ho cercato in rete e sulle risorse trovate suggeriscono di aumentare BooleanQuery.SetMaxClauseCount ().
Questo suona strano per me .. A cosa dovrei farlo? Come posso fare affidamento sul fatto che questo nuovo numero magico sarà sufficiente per la mia query? Fino a che punto posso aumentare questo numero prima che si scateni l'inferno?

In generale, ritengo che questa non sia una soluzione. Deve esserci un problema più profondo ..

La query era + {+ companyName: mercedes + paintCode: a *} e l'indice ha ~ 2,5 milioni di documenti.

È stato utile?

Soluzione

the paintCode: una parte * della query è una query con prefisso per qualsiasi paintCode che inizia con un " a " ;. È quello che stai mirando?

Lucene espande le query del prefisso in una query booleana contenente tutti i termini possibili che corrispondono al prefisso. Nel tuo caso, a quanto pare ci sono più di 1024 possibili paintCode che iniziano con un " a " ;.

Se ti sembra che le query con prefissi siano inutili, non sei lontano dalla verità.

Suggerirei di modificare lo schema di indicizzazione per evitare di utilizzare una query prefisso. Non sono sicuro di ciò che stai tentando di realizzare con il tuo esempio, ma se vuoi cercare i codici di vernice per prima lettera, crea un campo paintCodeFirstLetter e cerca per quel campo.

AGGIUNTO

Se sei disperato e sei disposto ad accettare risultati parziali, puoi creare la tua versione di Lucene dalla fonte. È necessario apportare modifiche ai file PrefixQuery.java e MultiTermQuery.java , entrambi in org / apache / lucene / search . Nel metodo rewrite di entrambe le classi, cambia la riga

query.add(tq, BooleanClause.Occur.SHOULD);          // add to query

a

try {
    query.add(tq, BooleanClause.Occur.SHOULD);          // add to query
} catch (TooManyClauses e) {
    break;
}

L'ho fatto per il mio progetto e funziona.

Se davvero non ti piace l'idea di cambiare Lucene, potresti scrivere la tua variante PrefixQuery e il tuo QueryParser, ma non penso che sia molto meglio.

Altri suggerimenti

Sembra che tu lo stia utilizzando in un campo che è una specie di tipo Parola chiave (il che significa che non ci saranno più token nel campo dell'origine dati).

C'è un suggerimento che mi sembra abbastanza elegante: http://grokbase.com/t/lucene.apache.org/java-user/2007/11/substring-indexing-to-avoid-toomanyclauses-exception/ 12f7s7kzp2emktbn66tdmfpcxfya

L'idea di base è quella di suddividere il termine in più campi con lunghezza crescente fino a quando non si è abbastanza sicuri di non raggiungere il limite della clausola.

Esempio:

Immagina un paintCode come questo:

"a4c2d3"

Quando si indicizza questo valore, si creano i seguenti valori di campo nel documento:

[paintCode]: "a4c2d3"

[paintCode1n]: "a"

[paintCode2n]: "a4"

[paintCode3n]: "a4c"

Al momento della query, il numero di caratteri del termine decide in quale campo cercare. Ciò significa che eseguirai una query con prefisso solo per i termini con più di 3 caratteri, il che riduce notevolmente il conteggio dei risultati interni, impedendo il famigerato TooManyBooleanClausesException . Apparentemente questo velocizza anche il processo di ricerca.

È possibile automatizzare facilmente un processo che suddivide automaticamente i termini e riempie i documenti con valori secondo uno schema di nomi durante l'indicizzazione.

Alcuni problemi possono sorgere se si hanno più token per ciascun campo. Puoi trovare maggiori dettagli nell'articolo

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top