反向嵌套聚合编辑

一种特殊的单桶聚合,它允许对嵌套文档中的父文档进行聚合。实际上,此聚合可以跳出嵌套块结构并链接到其他嵌套结构或根文档,这允许在嵌套聚合中嵌套其他不属于嵌套对象的聚合。

reverse_nested 聚合必须定义在 nested 聚合内。

选项

  • path - 定义要连接回哪个嵌套对象字段。默认值为空,这意味着它连接回根/主文档级别。路径不能包含对落在 nested 聚合的嵌套结构之外的嵌套对象字段的引用,即 reverse_nested 所在的结构。

例如,假设我们有一个用于票证系统的索引,其中包含问题和评论。评论作为嵌套文档内联到问题文档中。映射可能如下所示

response = client.indices.create(
  index: 'issues',
  body: {
    mappings: {
      properties: {
        tags: {
          type: 'keyword'
        },
        comments: {
          type: 'nested',
          properties: {
            username: {
              type: 'keyword'
            },
            comment: {
              type: 'text'
            }
          }
        }
      }
    }
  }
)
puts response
PUT /issues
{
  "mappings": {
    "properties": {
      "tags": { "type": "keyword" },
      "comments": {                            
        "type": "nested",
        "properties": {
          "username": { "type": "keyword" },
          "comment": { "type": "text" }
        }
      }
    }
  }
}

comments 是一个数组,它在 issue 对象下保存嵌套文档。

以下聚合将返回评论过且每个顶级评论者评论过的问题的顶级标签的顶级评论者的用户名

response = client.search(
  index: 'issues',
  body: {
    query: {
      match_all: {}
    },
    aggregations: {
      comments: {
        nested: {
          path: 'comments'
        },
        aggregations: {
          top_usernames: {
            terms: {
              field: 'comments.username'
            },
            aggregations: {
              comment_to_issue: {
                reverse_nested: {},
                aggregations: {
                  top_tags_per_comment: {
                    terms: {
                      field: 'tags'
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
)
puts response
GET /issues/_search
{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "comments": {
      "nested": {
        "path": "comments"
      },
      "aggs": {
        "top_usernames": {
          "terms": {
            "field": "comments.username"
          },
          "aggs": {
            "comment_to_issue": {
              "reverse_nested": {}, 
              "aggs": {
                "top_tags_per_comment": {
                  "terms": {
                    "field": "tags"
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

如上所示,reverse_nested 聚合被放入 nested 聚合中,因为这是 dsl 中唯一可以使用 reverse_nested 聚合的地方。它的唯一目的是连接回嵌套结构中更高层的父文档。

一个连接回根/主文档级别的 reverse_nested 聚合,因为没有定义 path。通过 path 选项,reverse_nested 聚合可以连接回不同的级别,如果在映射中定义了多层嵌套对象类型

可能的响应片段

{
  "aggregations": {
    "comments": {
      "doc_count": 1,
      "top_usernames": {
        "doc_count_error_upper_bound" : 0,
        "sum_other_doc_count" : 0,
        "buckets": [
          {
            "key": "username_1",
            "doc_count": 1,
            "comment_to_issue": {
              "doc_count": 1,
              "top_tags_per_comment": {
                "doc_count_error_upper_bound" : 0,
                "sum_other_doc_count" : 0,
                "buckets": [
                  {
                    "key": "tag_1",
                    "doc_count": 1
                  }
                  ...
                ]
              }
            }
          }
          ...
        ]
      }
    }
  }
}