Эластичный поиск: запрос по нескольким полям

У меня есть документ JSON в эластичном поиске следующим образом

{
  "animals": [
    {
      "id": 1,
      "name": "cat"
    },
    {
      "id": 2,
      "name": "dog"
    },
    {
      "id": 3,
      "name": "rabbit"
    }
  ]
}

Как запросить возврат этого документа только при наличии всех трех животных?

Это не работает.

curl -H 'Content-Type: application/json' -XPOST http://localhost:9200/*animals*/_search -d '{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "animals.name.keyword": "dog"
          }
        },
        {
          "term": {
            "animals.name.keyword": "cat"
          }
        },
        {
          "term": {
            "animals.name.keyword": "rabbit"
          }
        }
      ],
      "must_not": [],
      "should": []
    }
  }
}'

person rahul    schedule 23.06.2019    source источник
comment
Можете ли вы проверить сопоставление для вашего индекса? Я только что попытался создать индекс с вашими образцами данных и получил его с помощью вашего запроса. Оставляет проблему с чем-то другим, например сопоставлением, которое не соответствует запросу.   -  person Olivier    schedule 24.06.2019
comment
почему вы добавляете should и оставляете must_not?   -  person user156327    schedule 24.06.2019
comment
это работает как шарм для меня тоже. Но ответ Вэла стоит рассмотреть для этого варианта использования.   -  person Pierre Mallet    schedule 24.06.2019


Ответы (1)


Чтобы добиться того, что вы хотите, убедитесь, что animals имеет вложенный тип в вашем индексном отображении:

PUT animals
{
  "mappings": {
    "properties": {
      "animals": {
        "type": "nested"
      }
    }
  }
}

Тогда ваш запрос должен выглядеть так:

curl -H 'Content-Type: application/json' -XPOST http://localhost:9200/*animals*/_search -d '{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "animals",
            "query": {
              "term": {
                "animals.name.keyword": "dog"
              }
            }
          }
        },
        {
          "nested": {
            "path": "animals",
            "query": {
              "term": {
                "animals.name.keyword": "cat"
              }
            }
          }
        },
        {
          "nested": {
            "path": "animals",
            "query": {
              "term": {
                "animals.name.keyword": "rabbit"
              }
            }
          }
        }
      ]
    }
  }
}'
person Val    schedule 24.06.2019
comment
Я не понимаю, почему вы говорите, что в этом случае нужно вложенное поле. Без вложенного поля образец документа будет иметь [собака, кошка, кролик] в качестве значения для поля animals.name.keyword. Таким образом, запрос с предложением 3 must будет работать. На самом деле, когда я воспроизводлю в локальном режиме, он работает отлично. Я ошибаюсь? - person Pierre Mallet; 24.06.2019
comment
@PierreMallet Вы также можете добиться того же, не используя поля nested, однако имейте в виду, что если вам когда-нибудь понадобится применить второе условие к другому вложенному полю, оно больше не будет работать, и вы будете поджарены - person Val; 24.06.2019