ElasticSearch DSL Соответствие всем элементам запроса в списке списка строк

Я пытаюсь запросить ElasticSearch для соответствия каждому документу, который в списке списка содержит все запрошенные значения, но я не могу найти идеальный запрос.

Отображение:

        "id" : {
          "type" : "keyword"
        },
        "mainlist" : {
          "properties" : {
            "format" : {
              "type" : "keyword"
            },
            "tags" : {
              "type" : "keyword"
            }
          }
        },
        ...

Документы:

doc1 {
   "id" : "abc",
   "mainlist" : [
            {
              "type" : "big",
              "tags" : [
                "tag1",
                "tag2"
              ]
             },
             {
              "type" : "small",
              "tags" : [
                "tag1"
              ]
             }
    ]
},
doc2 {
   "id" : "abc",
   "mainlist" : [
            {
              "type" : "big",
              "tags" : [
                "tag1"
              ]
             },
            {
              "type" : "small",
              "tags" : [
                "tag2"
              ]
             }
    ]
},
doc3 {
   "id" : "abc",
   "mainlist" : [
            {
              "type" : "big",
              "tags" : [
                "tag1"
              ]
             }
    ]
}

Запрос, который я пробовал, приблизил меня к результату:

GET /index/_doc/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "mainlist.tags": "tag1"
          }
        },
        {
          "term": {
            "mainlist.tags": "tag2"
          }
        }
      ]
    }
  }
}

хотя в результате я получаю doc1 и doc2, хотя мне бы хотелось, чтобы doc1 содержал только tag1 и tag2 в одном элементе списка и не распространялся по обоим подспискам.

Как бы я смог этого добиться? Спасибо за любую помощь.

Добро пожаловать в Stackoverflow, просмотрите мой ответ и дайте мне знать, если вам нужна дополнительная информация.

Amit 18.03.2022 04:32
1
1
44
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

используйте тип вложенного поля, это работа для него https://www.elastic.co/guide/en/elasticsearch/reference/8.1/nested.html

Спасибо! У меня есть несколько других блоков с вложенным типом, которые я смог запросить, но мне было интересно, возможно ли это без «вложенности», возможно, с использованием безболезненного сценария, так как я не смогу переиндексировать все как вложенные в данный момент . Но это определенно правильное решение, я согласен. Спасибо за подтверждение @caster

Fabio Quinzi 18.03.2022 11:18
Ответ принят как подходящий

Как упоминал @caster, вам нужно использовать вложенный тип данных и запрос, как обычно, Elasticsearch рассматривает их как объект, и связь между элементами теряется, как описано в официальный документ.

Вам нужно изменить как сопоставление, так и запрос, чтобы получить желаемый результат, как показано ниже.

Отображение индекса

{
    "mappings": {
        "properties": {
            "id": {
                "type": "keyword"
            },
            "mainlist" :{
                "type" : "nested"
            }
        }
    }
}

Образец индексного документа по вашему примеру, без изменений

Запрос

{
    "query": {
        "nested": {
            "path": "mainlist",
            "query": {
                "bool": {
                    "must": [
                        {
                            "term": {
                                "mainlist.tags": "tag1"
                            }
                        },
                        {
                            "match": {
                                "mainlist.tags": "tag2"
                            }
                        }
                    ]
                }
            }
        }
    }
}

И результат

hits": [
            {
                "_index": "71519931_new",
                "_id": "1",
                "_score": 0.9139043,
                "_source": {
                    "id": "abc",
                    "mainlist": [
                        {
                            "type": "big",
                            "tags": [
                                "tag1",
                                "tag2"
                            ]
                        },
                        {
                            "type": "small",
                            "tags": [
                                "tag1"
                            ]
                        }
                    ]
                }
            }
        ]

Спасибо @Amit, это очень полезно, как упоминалось в комментарии к Caster, я искал решение, даже используя сценарии для его адресации в «невложенной» структуре, но планирую полную переиндексацию с «вложенной»

Fabio Quinzi 18.03.2022 11:19

Другие вопросы по теме