Как выполнять отрицательные запросы к вложенным объектам в Elasticsearch?

#elasticsearch

#elasticsearch

Вопрос:

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

 {
  "_doc": {
    "dynamic": "strict",
    "properties": {
      "things": {
        "type": "nested",
        "dynamic": "strict",
        "properties": {
          "name": {
            "type": "keyword"
          },
          "version": {
            "type": "keyword"
          }
        }
      }
    }
  }
}
  

Я хочу получить все документы, у которых нет каких-либо в них вложенных объектов-объектов с определенным набором значений. Запросы, подобные

 {
  "query": {
    "nested": {
      "path": "things",
      "query": {
        "bool": { 
          "must_not": [
            {
              "term": {
                "name": "thing1"
              }
            },
            {
              "term": {
                "version": "1.0.0"
              }
            }
          ]
        }
      }
    }
  }
}
  

кажется, что просто возвращаются все документы, в которых есть какой-то вложенный документ, который не соответствует… это означает, что он по-прежнему возвращает все документы, даже те, у которых также есть соответствующий вложенный объект. Итак, как мне правильно их отфильтровать?

РЕДАКТИРОВАТЬ: запросы, подобные

 {
  "query": {
    "bool": {
      "must_not": [
        {
          "nested": {
            "path": "things",
            "query": {
              "bool": { 
                "must": [
                  {
                    "term": {
                      "name": "thing1"
                    }
                  },
                  {
                    "term": {
                      "version": "1.0.0"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}
  

которые помещают запрос вложенного объекта внутрь must_not также не работают и по-прежнему просто возвращают все.

Комментарии:

1. Насколько я знаю: ваш вложенный запрос будет применяться к тому, что найдено, но для этого вложенного типа. Что вам, вероятно, нужно, так это функция-оболочка, которая сделает ваш запрос вложенным запросом must , но ваш фактический запрос: query: { bool: { must_not: [ nestedQuery - that does find things ] } } Это не идеально, но я нашел обходной путь

2. @Tessmore К сожалению, это, похоже, тоже не работает. 🙁

3. Оки, возможно, я не совсем понимаю: Если вы не хотите использовать thing1 в качестве имени ИЛИ version = 1.0.0 , то вложенной штукой может быть should и теперь, когда я прочитал это снова, я думаю, что это то, что вы имеете в виду? Таким образом, запрос bool внутри вложенного запроса может быть should . Если ваш вариант использования отличается, возможно, покажите пример документа, который соответствует, и тот, который не должен (но сейчас возвращается)

Ответ №1:

Ну, в конце концов, я сам это понял. Оказывается, что, несмотря на явное указание path поля в запросе вложенного объекта, имена полей вложенных объектов все еще должны быть полными. Таким образом, это работает:

 {
  "query": {
    "nested": {
      "path": "things",
      "query": {
        "bool": { 
          "must_not": [
            {
              "term": {
                "things.name": "thing1"
              }
            },
            {
              "term": {
                "things.version": "1.0.0"
              }
            }
          ]
        }
      }
    }
  }
}