弹性搜索中的嵌套查询

Nested Query in Elastic Search

我在这种形式的弹性搜索中有一个模式:

{
   "index1" : {
      "mappings" : {
         "properties" : {
            "key1" : {
               "type" : "keyword"
            },
            "key2" : {
               "type" : "keyword"
            },
            "key3" : {
               "properties" : {
                  "components" : {
                     "type" : "nested",
                     "properties" : {
                        "sub1" : {
                           "type" : "keyword"
                        },
                        "sub2" : {
                           "type" : "keyword"
                        },
                        "sub3" : {
                           "type" : "keyword"
                        }
                     }
                  }
               }
            }
         }
      }
   }
}

然后弹性搜索中存储的数据格式为:

{
   "_index" : "index1",
   "_type" : "_doc",
   "_id" : "1",
   "_score" : 1.0,
   "_source" : {
      "key1" : "val1",
      "key2" : "val2",
      "key3" : {
         components : [
            {
               "sub1" : "subval11",
               "sub3" : "subval13"
            },
            {
               "sub1" : "subval21",
               "sub2" : "subval22",
               "sub3" : "subval23"
            },
            {
               "sub1" : "subval31",
               "sub2" : "subval32",
               "sub3" : "subval33"
            }
         ]
      }
   }
}

如您所见,sub1、sub2 和 sub3 可能不存在于 key3 下的少数对象中。

现在,如果我尝试编写一个查询来获取基于 key3.sub2 的结果,如 subval22 使用此查询

GET index1/_search
{
  "query": {
    "nested": {
      "path": "components",
      "query": {
        "bool": {
          "must": [
            {
              "match": {"key3.sub2": "subval22"}
            }
          ]
        }
      }
    }
  }
}

我总是得到错误

{
  "error": {
    "root_cause": [
      {
        "type": "query_shard_exception",
        "reason": "failed to create query: {...}",
        "index_uuid": "1",
        "index": "index1"
      }
    ],
    "type": "search_phase_execution_exception",
    "reason": "all shards failed",
    "phase": "query",
    "grouped": true,
    "failed_shards": [
      {
        "shard": 0,
        "index": "index1",
        "node": "1aK..",
        "reason": {
          "type": "query_shard_exception",
          "reason": "failed to create query: {...}",
          "index_uuid": "1",
          "index": "index1",
          "caused_by": {
            "type": "illegal_state_exception",
            "reason": "[nested] failed to find nested object under path [components]"
          }
        }
      }
    ]
  },
  "status": 400
}

我了解到,由于 sub2 并非存在于组件下的所有对象中,因此会引发此错误。我正在寻找一种方法来搜索此类场景,以便它匹配并找到数组中的所有对象。如果匹配到某个值,则应返回此文档。

谁能帮我解决这个问题。

您在定义架构时犯了错误,下面的架构工作正常,注意 我刚刚将 key3 定义为嵌套。并将嵌套路径更改为 key3

索引定义

{
    "mappings": {
        "properties": {
            "key1": {
                "type": "keyword"
            },
            "key2": {
                "type": "keyword"
            },
            "key3": {
                "type": "nested"
            }
        }
    }
}

索引您的示例文档,无需任何更改

 {
  "key1": "val1",
  "key2": "val2",
  "key3": {
    "components": [ --> this was a diff
      {
        "sub1": "subval11",
        "sub3": "subval13"
      },
      {
        "sub1": "subval21",
        "sub2": "subval22",
        "sub3": "subval23"
      },
      {
        "sub1": "subval31",
        "sub2": "subval32",
        "sub3": "subval33"
      }
    ]
  }
}

正在根据您的条件进行搜索

 {
    "query": {
        "nested": {
            "path": "key3", --> note this
            "query": {
                "bool": {
                    "must": [
                        {
                            "match": {
                                "key3.components.sub2": "subval22" --> note this
                            }
                        }
                    ]
                }
            }
        }
    }
}

这会带来正确的搜索结果

   "hits": [
      {
        "_index": "so_nested_61200509",
        "_type": "_doc",
        "_id": "2",
        "_score": 0.2876821,
        "_source": {
          "key1": "val1",
          "key2": "val2",
          "key3": {
            "components": [ --> note this
              {
                "sub1": "subval11",
                "sub3": "subval13"
              },
              {
                "sub1": "subval21",
                "sub2": "subval22",
                "sub3": "subval23"
              },
              {
                "sub1": "subval31",
                "sub2": "subval32",
                "sub3": "subval33"
              }
            ]

编辑:- 根据 OP 的评论,更新示例文档、搜索查询和结果。