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

Я работаю над запросом Solr, похожим на следующее:

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

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

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

6 ответов

Решение

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

-(myField:superneat AND -myOtherField:somethingElse)

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

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

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

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

-foo превращается Solr в (*:* -foo)

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

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

?q=-title:foo&debug=query

превращается в

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

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

(my_field=my_value или my_field равно нулю):

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

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

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

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

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

*:* 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

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

Другие вопросы по тегам