如何在 Elasticsearch 中通过文档数组中的多个对象字段进行查询?

How to query by multiple fields of object in array of a document in Elasticsearch?

大家好,我是 Elasticsearch 的新手。我想通过其字段(类型:数组)的值来查询文档。示例如下:

docx=people:[
{id:1,role:admin},
{id:2,role:other}
]
docy=people:[
{id:1,role:other},
{id:2,role:admin}
]

我的查询是people.id:1 AND people.role:admin。我的预期结果只有 docx,但 ES 也 returns docy。我知道这是错误的,但我怎么能在 ES 中做到这一点。那么查询字符串如何只过滤像 docx 这样的文档。谢谢!

您需要在您的情况下使用 nested data-type,因为对象 data-type 被展平并单独处理,这导致两个文档都匹配结果,将添加一个工作示例。

但请注意,当您有大量 data-set 和大量并发查询时,嵌套 data-type 会变得昂贵,如 go-jek's medium blog.

中所述

请关注 this 博客,其中详细突出了您的问题。

正确映射的工作示例

索引映射

{
    "mappings": {
        "properties": {
            "name" : {
             "type" :   "text"
            },
            "people": {
                "type": "nested"
            }
        }
    }
}

索引示例文档

{
    "name": "bar",
    "people": 
    [
        {
            "id": 1,
            "role": "other"
        },
        {
            "id": 2,
            "role": "admin"
        }
    ]
}

和第二个示例文档

{
    "name": "foo",
    "people": 
    [
        {
            "id": 1,
            "role": "admin"
        },
        {
            "id": 2,
            "role": "other"
        }
    ]
}

搜索查询

{
    "query": {
        "nested": {
            "path": "people",
            "query": {
                "bool": {
                    "must": [
                        {
                            "match": {
                                "people.id": 1
                            }
                        },
                        {
                            "match": {
                                "people.role": "admin"
                            }
                        }
                    ]
                }
            }
        }
    }
}

和预期的搜索结果

"hits": [
            {
                "_index": "matchphrase",
                "_type": "_doc",
                "_id": "1",
                "_score": 1.6931472,
                "_source": {
                    "name": "foo",
                    "people": [
                        {
                            "id": 1,
                            "role": "admin"
                        },
                        {
                            "id": 2,
                            "role": "other"
                        }
                    ]
                }
            }
        ]