используя OR и NOT в запросе solr

84

Я работаю над запросом solr, подобным следующему:

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

При запуске результаты не возвращаются. Использование критериев по обе стороны от ИЛИ НЕ возвращает результаты, которых я ожидал - они просто не работают вместе. В случае, когда MyField соответствует superneat , я намерен также гарантировать , что myOtherField установлен в somethingElse , но если MyField не superneat , включить его в результатах поиска.

Может ли кто-нибудь объяснить, почему solr не возвращает результаты для такого рода запросов? Следует ли как-то реструктурировать запрос - или есть другой способ использования solr для достижения желаемого результата?

украденныйрис
источник

Ответы:

83

Я не знаю , почему это не работает, но это один логически эквивалентны , и это делает работу:

-(myField:superneat AND -myOtherField:somethingElse)

Возможно, это как-то связано с двойным определением одного и того же поля в запросе ...

Попробуйте спросить в группе пользователей solr , а затем отправьте здесь окончательный ответ!

Маурисио Шеффер
источник
1
Спасибо за помощь! Это действительно работает - и я сообщил об этом группе пользователей solr. Я размещу здесь все полезные вещи, которые услышу от них.
Stolenricecakes
9
Обратите внимание, что -myField:superneat OR myOtherField:somethingElseэто тоже будет то же самое, но немного проще.
Yorick Sijsling
4
@YorickSijsling, дело в том, что, хотя Solr логически эквивалентен, иногда он не очень хорошо справляется с чисто отрицательными запросами, такими как тот, который опубликовал OP, или тот, который вы опубликовали.
Маурисио Схеффер
1
@Mauricio Scheffer - я бы полностью усомнился в этом. Не могли бы вы объяснить, почему он не очень хорошо справляется? Мы запускаем здесь довольно сложные условные выражения и обнаружили, что они очень хорошо справляются с миллиардами документов.
terrance.a.snyder
1
@ terrance.a.snyder "сложные условия"! = "чисто отрицательные запросы". Кроме того, в последних версиях Solr ситуация могла улучшиться, я не проверял.
Маурисио Схеффер
44
Instead of "NOT [condition]" use "(*:* NOT [condition])"

источник
2
Большое спасибо! Этот подход работал у меня даже для сложных запросов, в то время как подход (myField: superneat AND -myOtherField: somethingElse) - нет!
dpetruha
34

В настоящее время Solr проверяет наличие «чисто отрицательного» запроса и вставляет *:*(который соответствует всем документам), чтобы он работал правильно.

-foo преобразуется solr в (*:* -foo)

Большое предостережение заключается в том, что Solr проверяет только, является ли запрос верхнего уровня чисто отрицательным запросом! Таким образом, это означает, что такой запрос bar OR (-foo)не изменяется, поскольку чисто отрицательный запрос находится в подпункте запроса верхнего уровня. Вам необходимо самостоятельно преобразовать этот запрос вbar OR (*:* -foo)

Вы можете проверить объяснение запроса solr, чтобы проверить преобразование запроса:

?q=-title:foo&debug=query

преобразован в

(+(-title:foo +MatchAllDocsQuery(*:*))
Йоник
источник
1
edismax правильно обрабатывает вложенные чисто отрицательные запросы, верно? Обсуждалось ли исправление парсера запросов Lucene для поддержки их таким же образом?
Питер Диксон-Мозес
25

Собирая вместе комментарии из пары разных ответов здесь, в документации Solr и по другому вопросу SO, я обнаружил, что следующий синтаксис дает правильный результат для моего варианта использования

(my_field = my_value или my_field имеет значение null):

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

Это работает для solr 4.1.0. Это немного отличается от варианта использования в OP; но я думал, что другие сочтут это полезным.

RMorrisey
источник
1
Рассмотрим именно этот сценарий сегодня в Solr 5, и это предложение работает.
Райан Шелли
10

Вы можете найти продолжение группы пользователей solr в списке рассылки пользователей solr

Преобладает мнение, что оператор NOT может использоваться только для удаления результатов из запроса, а не только для исключения вещей из всего набора данных. Мне нравится синтаксис, который вы предложили mausch - спасибо!

украденныйрис
источник
4

Чтобы добавить еще один неожиданный случай, вот запрос, который не возвращал ожидаемых результатов:

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

field_bв моем случае это то, над чем я выполняю фасетирование, и мне нужно было нацелить термин запроса "foo" только на этот тип (панель)

Мне пришлось вставить еще одно *:* после условия или, чтобы это работало, например:

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

изменить: это в solr 6.6.3

демонллама
источник
0

простой do id :( "12345") OR id :( "7890") .... и так далее

Нитин Дамле
источник