Использовать must_not exists с помощью elasticsearch_dsl

Для одного из моих проектов мне нужно определить все записи из моего индекса ES, в которых отсутствует поле. См. пример моих данных, хранящихся в моем индексе ES ниже:

{
  "schema": "https://sample.org/schemas/user_v0.0.1.json",
  "barcode": "210000001",
  "birth_date": "1961-11-24", 
  "first_name": "John",
  "last_name": "Doe",
  "subscriptions": [
    {
      "end_date": "2021-03-30",
      "start_date": "2020-03-30"
    }
  ]
}, {
  "schema": "https://sample.org/schemas/user_v0.0.1.json",
  "barcode": "210000002",
  "birth_date": "1980-03-17", 
  "first_name": "Bob",
  "last_name": "Smith",
  "subscriptions": []
}, {
  "schema": "https://sample.org/schemas/user_v0.0.1.json",
  "barcode": "210000003",
  "birth_date": "1980-03-17", 
  "first_name": "Patty",
  "last_name": "Smith"
}

Я хотел бы определить, у кого из моих пользователей нет подписок. В моем примере должны быть возвращены «Боб Смит» и «Пэтти Смит». Мне нужно сделать это с помощью запроса Python ElasticSearch DSL.

В настоящее время я могу отфильтровать свой поиск, чтобы получить только пользователей, но, несмотря на многие попытки, я не нашел способ получить подписки только пользователей «must_not» + «exists».

results = Search()\
          .filter('term', schema='https://sample.org/schemas/user_v0.0.1.json')
          # complete filter with : "Must not exists subscription"
          .source('barcode')
          .scan()

Спасибо за вашу помощь


person Renaud Michotte    schedule 01.04.2020    source источник


Ответы (2)


Я не знаком с Python DSL, но запрос REST для поиска тех пользователей, у которых нет подписок:

    {
     "query": {
    "bool": {
      "must_not": [
        {
          "nested": {
            "path": "subscriptions",
            "query": {
              "exists": {
                "field": "subscriptions"
              }
            }
          }
        }
      ]
    }
  }
person Community    schedule 01.04.2020

Продолжаю искать и тестировать и кажется нашел решение своей проблемы

    query = Search()\
        .filter('term', schema='https://sample.org/schemas/user_v0.0.1.json')\
        .filter('bool', must_not=[Q('exists', field="subscriptions")])\
        .source('barcode')\
        .scan()

Я надеюсь, что это может помочь кому-то!

person Renaud Michotte    schedule 01.04.2020
comment
Более лаконичный способ написать must_not exists — использовать метод .exclude(), например так: .exclude("exists", field="subscriptions") - person jmullercuber; 02.12.2020