używanie OR i NOT w zapytaniu solr


84

Pracuję nad zapytaniem solr podobnym do następującego:

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

Po uruchomieniu tego nie są zwracane żadne wyniki. Korzystanie z kryteriów po obu stronach LUB NIE zwraca wyniki, których bym się spodziewał - po prostu nie współpracują dobrze. W przypadku, myField pasuje superneat , jestem zamierza również zapewnić, że myOtherField jest ustawiony na somethingelse , ale jeśli myField nie jest superneat , umieścić go w wynikach.

Czy ktoś może wyjaśnić, dlaczego solr nie zwraca wyników dla tego rodzaju zapytania? Czy należy w jakiś sposób zrestrukturyzować zapytanie - czy może jest inny sposób wykorzystania solr do osiągnięcia pożądanego rezultatu?

Odpowiedzi:


83

Nie wiem, dlaczego to nie działa, ale ten jest logicznie równoważne i to czyni pracę:

-(myField:superneat AND -myOtherField:somethingElse)

Może ma to coś wspólnego z dwukrotnym zdefiniowaniem tego samego pola w zapytaniu ...

Spróbuj zapytać w grupie solr-user , a następnie zamieść tutaj ostateczną odpowiedź!


1
Dziękuję za pomoc! To rzeczywiście działa - i przedstawiłem to grupie solr-user. Opublikuję tutaj wszystkie przydatne informacje, które od nich usłyszę.
stolenricecakes

9
Zauważ, że -myField:superneat OR myOtherField:somethingElsebyłoby to takie samo i jest nieco prostsze.
Yorick Sijsling

4
@YorickSijsling chodzi o to, że chociaż logicznie równoważne, Solr czasami nie radzi sobie zbyt dobrze z czysto negatywnymi zapytaniami, takimi jak to, które opublikował OP lub to, które wysłałeś.
Mauricio Scheffer

1
@Mauricio Scheffer - zakwestionowałbym to całkowicie. Czy mógłbyś wyjaśnić więcej, dlaczego nie radzi sobie zbyt dobrze? Uruchamiamy tutaj dość złożone warunki warunkowe i stwierdziliśmy, że bardzo dobrze radzi sobie z miliardami dokumentów.
terrance.a.snyder

1
@ terrance.a.snyder "złożone warunki warunkowe"! = "czysto negatywne zapytania". Poza tym sytuacja mogła się poprawić w ostatnich wersjach Solr, nie sprawdzałem.
Mauricio Scheffer

44
Instead of "NOT [condition]" use "(*:* NOT [condition])"

2
Wielkie dzięki! Ten działał dla mnie nawet w przypadku złożonych zapytań, podczas gdy - (myField: superneat AND -myOtherField: somethingElse) podejście - nie!
dpetruha,

34

Solr obecnie sprawdza, czy nie ma zapytania „czysto negatywnego” i wstawia *:*(pasujące do wszystkich dokumentów), aby działało poprawnie.

-foo jest przekształcany przez solr w (*:* -foo)

Dużym zastrzeżeniem jest to, że Solr sprawdza tylko, czy zapytanie najwyższego poziomu jest czysto negatywne! Oznacza to, że zapytanie takie jak bar OR (-foo)nie jest zmieniane, ponieważ czyste zapytanie negatywne znajduje się w klauzuli podrzędnej zapytania najwyższego poziomu. Musisz samodzielnie przekształcić to zapytanie wbar OR (*:* -foo)

Możesz sprawdzić wyjaśnienie zapytania solr, aby zweryfikować transformację zapytania:

?q=-title:foo&debug=query

jest przekształcany do

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

1
edismax poprawnie obsługuje zagnieżdżone czyste zapytania negatywne, prawda? Czy była jakaś dyskusja na temat łatania parsera zapytań Lucene, aby obsługiwał je w ten sam sposób?
Peter Dixon-Moses

25

Zestawiając komentarze z kilku różnych odpowiedzi tutaj, w dokumentacji Solr i na drugim pytaniu SO, stwierdziłem, że następująca składnia daje poprawny wynik dla mojego przypadku użycia

(my_field = my_value lub my_field ma wartość null):

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

Działa to w solr 4.1.0. Jest to nieco inne niż przypadek użycia w PO; ale myślałem, że inni uznają to za przydatne.


1
Właśnie w ten scenariusz wpadłem dzisiaj w Solr 5 i ta sugestia działa.
Ryan Shelley

10

Śledzenie grupy solr-user można znaleźć na: lista mailling użytkowników solr

Przeważa myśl, że operator NOT może być używany tylko do usuwania wyników z zapytania - a nie tylko do wykluczania elementów z całego zbioru danych. Tak się składa, że ​​podoba mi się składnia, którą zasugerowałeś Mausch - dzięki!


4

Aby dodać kolejny nieoczekiwany przypadek, oto zapytanie, które nie zwróciło oczekiwanych wyników:

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

field_bw moim przypadku jest to coś, na czym wykonuję faceting, i potrzebowałem skierować zapytanie „foo” tylko na ten typ (bar)

Musiałem wstawić kolejny *:* po warunku lub, aby to zadziałało, na przykład:

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

edycja: to jest w solr 6.6.3


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.