Эластичные ИЛИ-опции работают не так, как я ожидал

#elasticsearch #lucene #elasticsearch-query

Вопрос:

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

 ...
"must": [
  {
    "query_string": {
      "analyze_wildcard": true,
      "query": "* AND (name:"NAME 1" OR name:"NAME 2" OR name:"NAME 3")"
    }
  },
...
 

вместо

 ...
"must": [
  {
    "query_string": {
      "analyze_wildcard": true,
      "query": "* AND name:"NAME 1" OR name:"NAME 2" OR name:"NAME 3""
    }
  },
...
 

Первый запрос возвращает все документы с ИМЕНЕМ 1, ИМЕНЕМ 2 и ИМЕНЕМ 3, но второй запрос возвращает только документы с ИМЕНЕМ термина 1.

кроме того, приведенный ниже запрос возвращает только ИМЯ 3

 ...
"must": [
  {
    "query_string": {
      "analyze_wildcard": true,
      "query": "name:"NAME 1" OR name:"NAME 2" OR name:"NAME 3" AND *"
    }
  },
...
 

Это не имеет смысла, потому что, если я создам запрос с несуществующим термином , таким как: " * AND name: "asdfasdfa " OR name: "NAME 2 " OR name: "NAME 3 " " , у меня будет пустой ответ и я буду думать об условных обозначениях кода:

true amp;amp; false || true || true является true

true amp;amp; (false || true || true) тоже true

и,

'a' amp;amp; null || 'b' || 'c' является 'b'

'a' amp;amp; (null || 'b' || 'c') тоже 'b'

Ответ №1:

Это тема приоритета операндов. Цитирование документов (выделено жирным шрифтом, добавленным мной):

Также поддерживаются знакомые логические операторы AND OR и NOT (также написанные amp;amp; || и!), Но будьте осторожны , чтобы они не соблюдали обычные правила приоритета, поэтому круглые скобки следует использовать всякий раз, когда несколько операторов используются вместе.

Итак, в случае запроса № 2 исходный:

 * AND name:"NAME 1" OR name:"NAME 2" OR name:"NAME 3"
 

внутренне преобразуется в запрос lucene:

  *:*  name:"name 1" name:"name 2" name:"name 3"
 

Как таковое, оно не может быть понято как:

 true amp;amp; false || true || true
 

что в стандартной булевой логике действительно было бы равно true .

Короче говоря, используйте круглые скобки, когда это применимо.


Кстати, термины в запросе lucene были написаны в нижнем регистре (анализируется standard анализатором), потому что вы указали analyze_wildcard:true . Это может быть или не быть именно тем, чего вы хотели бы, поэтому я подумал, что об этом стоит упомянуть!