ElasticSearch DSL匹配字符串列表中查询的所有元素

ElasticSearch DSL Matching all elements of query in list of list of strings

我正在尝试查询 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"
          }
        }
      ]
    }
  }
}

虽然我得到的结果是 doc1doc2,但我只希望 doc1 在单个列表元素中包含 tag1 和 tag2,而不是分布在两个子列表中。

我怎样才能做到这一点? 感谢您的帮助。

使用嵌套字段类型,这是可行的 https://www.elastic.co/guide/en/elasticsearch/reference/8.1/nested.html

如@caster所述,您需要使用nested data type and query as in normal way Elasticsearch treats them as object and relation between the elements are lost, as explained in offical doc

您需要同时更改映射和查询以获得所需的输出,如下所示。

索引映射

{
    "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"
                            ]
                        }
                    ]
                }
            }
        ]