Используя 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, а затем опубликуйте здесь окончательный ответ!
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