Como eu procuraria facetas em branco em um campo de facetas com vários valores e, ao mesmo tempo, no Solr?
-
20-09-2019 - |
Pergunta
Eu tenho um aplicativo onde os usuários podem escolher peças de carro. Eles escolhem o veículo e depois escolhem atributos do veículo como facetas. Depois de selecionar o veículo, eles podem escolher facetas como o tamanho do motor, por exemplo, para restringir a lista de resultados. O problema era que nem todos os documentos têm um tamanho de motor (é um valor vazio no Solr), pois não importa para todas as partes. Por exemplo, o tamanho do motor raramente importa para um filtro de ar. Portanto, mesmo que um usuário tenha escolhido 3.5L para o tamanho do motor, eu ainda queria mostrar os filtros de ar na tela como uma possível parte que o usuário poderia escolher. Eu fiz algumas pesquisas e a seguinte consulta de faceta funciona perfeitamente:
enginesize:"3.5" OR enginesize:(*:* AND -enginesize:[* TO *])
Essa consulta corresponderia a 3,5 ou corresponderia a registros onde não havia valor para o campo de tamanho do motor (nenhum valor significava que não importava e se encaixava no carro). Perfeito...
O PROBLEMA: Recentemente, fiz os campos de vários campos de atributos do veículo, para poder armazenar atributos para cada parte como uma lista. Eu então apliquei faceting a ele e funcionou bem. No entanto, o problema surgiu quando apliquei a consulta mencionada anteriormente acima. Ao selecionar a faceta do MONGINESize reduziu o número de documentos exibidos apenas para documentos que possuem o tamanho do motor, os registros (também uso o registro da palavra que significa documento) que tinham valores vazios (ou seja, "") para o MONGINESIZE não estavam aparecendo. A mesma consulta acima não funciona para facetas multivalugas da mesma maneira que quando o MOGINESSIZE era um único campo de valor.
Exemplo:
<doc>
<str name="part">engine mount</str>
<arr name="enginesize">
<str/>
<str/>
<str>3.5</str>
<str>3.5</str>
<str>3.5</str>
<str>3.5</str>
<str>3.5</str>
</arr>
<doc>
<doc>
<str name="part">engine bolt</str>
<arr name="enginesize">
<str>6</str>
<str>6</str>
<str>6</str>
<str>6</str>
<str>6</str>
</arr>
<doc>
<doc>
<str name="part">air filter</str>
<arr name="enginesize">
<str/>
<str/>
<str></str>
<str></str>
<str></str>
<str></str>
<str></str>
</arr>
<doc>
O que estou procurando é uma consulta que retire os documentos 1 e 3 acima, quando eu fizer uma faceta pelo tamanho do motor para 3,5. O primeiro documento (a montagem do motor) corresponde, porque contém o valor em um dos campos de vários campos "Motinesize" que estou procurando (contém 3,5 em um dos campos). No entanto, o terceiro documento para o filtro de ar não é devolvido por causa do vazio <str>
valores. Eu não quero devolver o segundo documento, porque ele não corresponde ao valor da faceta
Eu basicamente quero uma consulta que corresponda aos valores de string vazios para uma determinada faceta e também correspondam ao valor real, para que os dois documentos retornem.
Alguém tem uma consulta que retornaria o documento 1 e o documento 3 (o suporte do motor e o filtro de ar), mas não o documento do parafuso do motor?
Eu tentei o seguinte sem sucesso (incluindo o no topo desta pergunta):
// returns everything
enginesize:"3.5" OR (enginesize:[* TO *] )
// only returns document 1
enginesize:"3.5" OR (enginesize:["" TO ""] AND -enginesize:"3.5")
// only returns document 1
enginesize:"3.5" OR (enginesize:"")
Eu importei os dados acima usando um arquivo CSV, eu defino o campo keepEmpty=true
. Em vez disso, tentei inserir manualmente um espaço no campo quando gerei o arquivo CSV (o que lhe daria <str> </str>
, em vez do anterior, e depois repetiu as consultas. Fazendo isso, obtive os seguintes resultados:
// returns document 1
enginesize:"3.5" OR enginesize:(*:* AND -enginesize:[* TO *])
// returns all documents
enginesize:"3.5" OR (enginesize:["" TO ""] AND -enginesize:"3.5")
// returns all documents
enginesize:"3.5" OR (enginesize:"")
Alguém tem uma consulta que funcionaria para qualquer situação, se eu tenho um espaço como valor em branco ou simplesmente nenhum valor?
Solução
Que tal mudar a forma como você indexa, em vez de como você pergunta?
Em vez de tentar indexar "O tamanho do motor não importa" como um registro vazio, indexa -o como "qualquer".
Então sua consulta simplesmente se torna o MONGINESIZE: "3.5" ou (MONEGINESize: qualquer)
Outras dicas
Acabei de brincar com isso e encontrei um dica Isso parece fazer o truque para mim. Traduzido para sua consulta, deve ser:
enginesize:"3.5" OR (-enginesize:["" TO *])
hth,
e eu
ATUALIZAÇÃO: Depois de mais alguns testes, não acho que isso funcione de maneira confiável - para alguns índices, tinha que ser o contrário e sem o sinal de menos, ou seja, enginesize:[* TO ""]
. Isso pode depender do tipo de índice, se for com vários valores ou mesmo dos valores reais.
De qualquer forma, parece um hack demais. Provavelmente vou resolver substituir o valor vazio por um marcador especial ...
Eu tive o mesmo problema, mas resolvi em https://stackoverflow.com/a/35633038/13365:
enginesize:"3.5" OR (*:* NOT enginesize:["" TO *])
o -enginesize
A solução não funcionou para mim.