Pergunta

Nos meus testes, de repente encontrei uma exceção de muitas cláusulas ao tentar obter os hits de uma consulta booleana que consistia em um TermQuery e uma consulta curinga.

Eu procurei pela rede e com os recursos encontrados que eles sugerem para aumentar o booleanQuery.setMaxclaUseCount ().
Isso me parece suspeito .. para o que devo melhorar? Como posso confiar que esse novo número mágico será suficiente para minha consulta? Até onde posso incrementar esse número antes que todo o inferno se solte?

Em geral, sinto que isso não é uma solução. Deve haver um problema mais profundo ..

A consulta foi +{ +CompanyName: Mercedes +PaintCode: A*} e o índice possui ~ 2,5m documentos.

Foi útil?

Solução

O PaintCode: A* Parte da consulta é uma consulta de prefixo para qualquer código de tinta que começa com um "A". É isso que você está buscando?

O Lucene expande consultas de prefixo em uma consulta booleana contendo todos os termos possíveis que correspondem ao prefixo. No seu caso, aparentemente existem mais de 1024 possíveis paintCodeS que começam com um "A".

Se parecer que você gosta de consultas de prefixo é inútil, você não está longe da verdade.

Eu sugiro que você altere seu esquema de indexação para evitar o uso de uma consulta de prefixo. Não tenho certeza do que você está tentando realizar com o seu exemplo, mas se você deseja procurar códigos de pintura pela primeira letra, faça um campo PaintCodeFirstletter e pesquise nesse campo.

ADICIONADO

Se você estiver desesperado e está disposto a aceitar resultados parciais, pode criar sua própria versão do Lucene a partir da fonte. Você precisa fazer alterações nos arquivos PrefixQuery.java e MultiTermQuery.java, ambos abaixo org/apache/lucene/search. No rewrite Método de ambas as classes, mude a linha

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

para

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

Eu fiz isso para o meu próprio projeto e funciona.

Se você realmente não gosta da ideia de mudar o Lucene, pode escrever sua própria variante de prefixija e seu próprio QueryParser, mas não acho que seja muito melhor.

Outras dicas

Parece que você está usando isso em um campo que é uma espécie de Palavra -chave Tipo (o que significa que não haverá vários tokens no seu campo de fonte de dados).

Há uma sugestão aqui que me parece bastante elegante: http://grokbase.com/t/lucene.apache.org/java-user/2007/11/substring-indexing-to-avoid-toomanyclaus-exception/12f7s7kzp2emktbn66tdmfpcxfya

A idéia básica é dividir seu termo em vários campos com um comprimento crescente até ter certeza de que não atingirá o limite da cláusula.

Exemplo:

Imagine um código de tinta como este:

"a4c2d3"

Ao indexar esse valor, você cria os seguintes valores de campo em seu documento:

[paintCode]: "a4c2d3"

[paintCode1n]: "a"

[paintCode2n]: "a4"

[paintCode3n]: "a4c"

Quando você consultar, o número de caracteres em seu termo decidir em qual campo pesquisar. Isso significa que você realizará uma consulta de prefixo Para termos com mais de 3 caracteres, o que diminui bastante a contagem de resultados internos, impedindo o infame ToomanyBooleanclaUsesexception. Aparentemente, isso também acelera o processo de pesquisa.

Você pode automatizar facilmente um processo que divide os termos automaticamente e preenche os documentos com valores de acordo com um esquema de nome durante a indexação.

Alguns problemas podem surgir se você tiver vários tokens para cada campo. Você pode encontrar mais detalhes no artigo

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top