嵌套对象查询edit

由于嵌套对象被索引在单独的隐藏的文档中,无法直接查询。相应地,必须使用 nested 查询 去获取:

GET /my_index/blogpost/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "title": "eggs" 
          }
        },
        {
          "nested": {
            "path": "comments", 
            "query": {
              "bool": {
                "must": [ 
                  {
                    "match": {
                      "comments.name": "john"
                    }
                  },
                  {
                    "match": {
                      "comments.age": 28
                    }
                  }
                ]
              }
            }
          }
        }
      ]
}}}

title 子句是查询根文档的。

nested 子句作用于嵌套字段 comments 。在此查询中,既不能查询根文档字段,也不能查询其他嵌套文档。

comments.namecomments.age 子句操作同一个嵌套文档。

nested 字段可以包含其他的 nested 字段。同样地,nested 查询也可以包含其他的 nested 查询。而嵌套的层次会按照你所期待的被应用。

当然,一个nested查询可以匹配多个嵌套文档。每一个匹配的嵌套文档都有自己的相关度得分,但是这众多的分数最终需要汇聚为可供根文档使用的一个分数。

默认情况下,根文档的分数是这些嵌套文档分数的平均值。可以通过设置 score_mode 参数来控制这个得分策略,相关策略有 avg (平均值), max (最大值), sum (求和) 和 none (直接返回固定分数值1.0)。

GET /my_index/blogpost/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "title": "eggs"
          }
        },
        {
          "nested": {
            "path": "comments",
            "score_mode": "max", 
            "query": {
              "bool": {
                "must": [
                  {
                    "match": {
                      "comments.name": "john"
                    }
                  },
                  {
                    "match": {
                      "comments.age": 28
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

返回最佳匹配的嵌套文档的_score给根文档。

如果 nested 查询放在一个布尔查询的 filter 子句中,其表现就像一个 nested 查询,只是 score_mode 参数不再生效。因为它被用于不打分的查询中 — 只是符合或不符合条件,不打分 — 那么 score_mode 就没有任何意义,因为根本就没有要打分的地方。