використовуючи АБО і НЕ у запиті solr


83

Я працюю над запитом solr, подібним до такого:

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

При запуску цього результати не повертаються. Використання критеріїв з обох сторін АБО НЕ повертає результати, які я очікував - вони просто погано працюють разом. У випадку, якщо myField відповідає супернету , я маю намір також переконатися, що для myOtherField встановлено значення somethingElse , але якщо myField не є супернитом , включіть його в результати.

Хтось може пояснити, чому solr не повертає результати для такого роду запитів? Чи слід якось реструктурувати запит - чи існує інший спосіб, за допомогою якого сольер можна досягти бажаного результату?

Відповіді:


82

Я не знаю , чому це не працює, але це один логічно еквівалентні , і це робить роботу:

-(myField:superneat AND -myOtherField:somethingElse)

Можливо, це пов’язано із визначенням одного і того ж поля двічі у запиті ...

Спробуйте запитати в групі користувачів-користувачів , а потім розмістіть тут остаточну відповідь!


Дякую за твою допомогу! Це справді працює - і я поставив це групі користувачів-користувачів. Я розміщу тут будь-яке корисне, що почую від них.
stolenricecakes

8
Зауважте, що -myField:superneat OR myOtherField:somethingElseце теж саме і трохи простіше.
Йорік Сійсслінг,

3
@YorickSijsling суть полягає в тому, що, хоча і логічно еквівалентний, Solr іноді не дуже добре справляється із суто негативними запитами, такими як той, який опублікував OP або той, який ви розмістили.
Mauricio Scheffer

@Mauricio Scheffer - Я б це повністю поставив під сумнів. Не могли б ви пояснити більше про те, як це не дуже добре справляється? Ми маємо тут досить складні умови, і ми виявили, що це дуже добре справляється з мільярдами документів.
terrance.a.snyder

@ terrance.a.snyder "складні умови"! = "суто негативні запити". Крім того, речі могли покращитися в останніх версіях Solr, я не перевіряв.
Маурісіо Шеффер

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

1
Подяка багато! Цей працював у мене навіть для складних запитів, тоді як - (myField: superneat І -myOtherField: somethingElse) підхід - ні!
dpetruha

33

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

-foo перетворюється сольром на (*:* -foo)

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

Ви можете перевірити пояснення запиту solr, щоб перевірити перетворення запиту:

?q=-title:foo&debug=query

перетворюється на

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

1
edismax правильно обробляє вкладені чисті негативні запити, так? Чи було якесь обговорення щодо виправлення синтаксичного аналізатора запитів Lucene для їх підтримки таким же чином?
Пітер Діксон-Мойсей

24

Склавши коментарі з декількох різних відповідей тут, у документах Solr та на інше запитання SO, я виявив, що наступний синтаксис дає правильний результат для мого випадку використання

(my_field = my_value або my_field є null):

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

Це працює для solr 4.1.0. Це дещо відрізняється від випадку використання в OP; але, я думав, що іншим це буде корисно.


1
Натрапив саме на цей сценарій сьогодні в Solr 5, і ця пропозиція працює.
Ryan Shelley

9

Ви можете знайти подальші дії щодо групи користувачів solr у: списку розсилки користувачів solr

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


3

Щоб додати ще один несподіваний випадок, ось запит, який не повертає очікуваних результатів:

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


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.