web-dev-qa-db-fra.com

using OR et NOT dans la requête solr

Je travaille sur une requête solr similaire à celle-ci:

((myField:superneat AND myOtherField:somethingElse) OR NOT myField:superneat)

Lors de l'exécution, aucun résultat n'est renvoyé. L’utilisation de critères de part et d’autre de OR NON renvoie les résultats que j’attendais - ils ne fonctionnent tout simplement pas bien ensemble. Dans le cas où myField correspond superneat , je compte également m'assurer que myOtherField est défini sur quelque chose d'Else , mais si myField n'est pas superneat , incluez-le dans les résultats.

Quelqu'un peut-il expliquer pourquoi solr ne renvoie pas de résultats pour ce type de requête? La requête doit-elle être restructurée d’une manière ou d’une autre - ou existe-t-il une manière différente d’utiliser solr pour obtenir le résultat souhaité?

81
stolenricecakes

Je ne sais pas pourquoi cela ne fonctionne pas, mais celui-ci est logiquement équivalent et cela fonctionne :

-(myField:superneat AND -myOtherField:somethingElse)

Peut-être que cela a quelque chose à voir avec la définition du même champ deux fois dans la requête ...

Essayez de demander dans le groupe d'utilisateurs , puis publiez à nouveau la réponse finale!

82
Mauricio Scheffer
Instead of "NOT [condition]" use "(*:* NOT [condition])"
39
MVMn

Solr recherche actuellement une requête "purement négatif" et insère *:* (Qui correspond à tous les documents) afin que cela fonctionne correctement.

-foo Est transformé par solr en (*:* -foo)

Le gros inconvénient est que Solr vérifie uniquement si la requête de niveau supérieur est une requête purement négative! Cela signifie donc qu'une requête telle que bar OR (-foo) n'est pas modifiée, car la requête négative pure se trouve dans une sous-clause de la requête de niveau supérieur. Vous devez vous-même transformer cette requête en bar OR (*:* -foo)

Vous pouvez vérifier l'explication de la requête solr pour vérifier la transformation de la requête:

?q=-title:foo&debug=query

est transformé en

(+(-title:foo +MatchAllDocsQuery(*:*))
33
Yonik

Rassemblant les commentaires de plusieurs réponses différentes ici, dans la documentation Solr et de l'autre SO question, j'ai constaté que la syntaxe suivante produit le résultat correct pour mon cas d'utilisation

(my_field = my_value ou my_field est null):

(my_field:"my_value" OR (*:* NOT my_field:*))

Cela fonctionne pour solr 4.1.0. Ceci est légèrement différent de celui utilisé dans le PO; mais, je pensais que d'autres le trouveraient utile.

23
RMorrisey

Vous pouvez trouver le suivi du groupe d’utilisateurs solr sur: liste des utilisateurs solr

L'idée qui prévaut est que l'opérateur NOT ne peut être utilisé que pour supprimer les résultats d'une requête, pas seulement pour exclure des éléments de l'ensemble de données. J'aime la syntaxe que vous avez suggérée mausch - merci!

8
stolenricecakes

Juste pour ajouter un autre cas inattendu, voici une requête qui n'a pas renvoyé les résultats attendus:

*:* AND ( ( field_a:foo AND field_b:bar ) OR !field_b:bar )

field_b dans mon cas, c’est quelque chose que j’exécute en facettes et que je devais cibler le terme de requête "foo" seulement sur ce type (barre)

Je devais insérer un autre *:* après la condition ou pour que cela fonctionne, comme ceci:

*:* AND ( ( field_a:foo AND field_b:bar ) OR ( *:* AND !field_b:bar ) )

edit: c'est dans Solr 6.6.3

3
demonllama