嵌套-集合

嵌套-集合

如同我们在查询时需要使用nested查询来存取嵌套对象,专门的nested集合使我们可以取得嵌套对象中栏位的集合:

  1. GET /my_index/blogpost/_search?search_type=count
  2. {
  3. "aggs": {
  4. "comments": { <1>
  5. "nested": {
  6. "path": "comments"
  7. },
  8. "aggs": {
  9. "by_month": {
  10. "date_histogram": { <2>
  11. "field": "comments.date",
  12. "interval": "month",
  13. "format": "yyyy-MM"
  14. },
  15. "aggs": {
  16. "avg_stars": {
  17. "avg": { <3>
  18. "field": "comments.stars"
  19. }
  20. }
  21. }
  22. }
  23. }
  24. }
  25. }
  26. }

<1> nested集合深入嵌套对象的comments栏位

<2> 评论基於comments.date栏位被分至各个月份分段

<3> 每个月份分段单独计算星号的平均数

结果显示集合发生於嵌套文档层级:

  1. ...
  2. "aggregations": {
  3. "comments": {
  4. "doc_count": 4, <1>
  5. "by_month": {
  6. "buckets": [
  7. {
  8. "key_as_string": "2014-09",
  9. "key": 1409529600000,
  10. "doc_count": 1, <1>
  11. "avg_stars": {
  12. "value": 4
  13. }
  14. },
  15. {
  16. "key_as_string": "2014-10",
  17. "key": 1412121600000,
  18. "doc_count": 3, <1>
  19. "avg_stars": {
  20. "value": 2.6666666666666665
  21. }
  22. }
  23. ]
  24. }
  25. }
  26. }
  27. ...

<1> 此处总共有四个comments: 一个在九月以及三个在十月

反向-嵌套-集合

反向嵌套-集合

一个nested集合只能存取嵌套文档中的栏位,而无法看见根文档或其他嵌套文档中的栏位。
然而,我们可以跳出嵌套区块,藉由reverse_nested集合回到父阶层。

举例来说,我们可以发现使用评论者的年龄为其加上tags很有趣。
comment.age是在嵌套栏位中,但是tags位於根文档:

  1. GET /my_index/blogpost/_search?search_type=count
  2. {
  3. "aggs": {
  4. "comments": {
  5. "nested": { <1>
  6. "path": "comments"
  7. },
  8. "aggs": {
  9. "age_group": {
  10. "histogram": { <2>
  11. "field": "comments.age",
  12. "interval": 10
  13. },
  14. "aggs": {
  15. "blogposts": {
  16. "reverse_nested": {}, <3>
  17. "aggs": {
  18. "tags": {
  19. "terms": { <4>
  20. "field": "tags"
  21. }
  22. }
  23. }
  24. }
  25. }
  26. }
  27. }
  28. }
  29. }
  30. }

<1> nested集合深入comments对象

<2> histogram集合以comments.age栏位聚集成每十年一个的分段

<3> reverse_nested集合跳回到根文档

<4> terms集合计算每个年龄分段的火红词语

简略的结果显示如下:

  1. ..
  2. "aggregations": {
  3. "comments": {
  4. "doc_count": 4, <1>
  5. "age_group": {
  6. "buckets": [
  7. {
  8. "key": 20, <2>
  9. "doc_count": 2, <2>
  10. "blogposts": {
  11. "doc_count": 2, <3>
  12. "tags": {
  13. "doc_count_error_upper_bound": 0,
  14. "buckets": [ <4>
  15. { "key": "shares", "doc_count": 2 },
  16. { "key": "cash", "doc_count": 1 },
  17. { "key": "equities", "doc_count": 1 }
  18. ]
  19. }
  20. }
  21. },
  22. ...

<1> 共有四个评论

<2> 有两个评论的发表者年龄介於20至30之间

<3> 两个blog文章与这些评论相关

<4> 这些blog文章的火红标签是sharescashequities

什麽时候要使用嵌套对象

嵌套对象对於当有一个主要实体(如blogpost),加上有限数量的紧密相关实体(如comments)是非常有用的。
有办法能以评论内容找到blog文章很有用,且nested查询及过滤器提供短查询时间连接(fast query-time joins)。

嵌套模型的缺点如下:

  • 如欲新增丶修改或删除一个嵌套文档,则必须重新索引整个文档。因此越多嵌套文档造成越多的成本。

  • 搜寻请求回传整个文档,而非只有匹配的嵌套文档。 虽然有个进行中的计画要支持只回传根文档及最匹配的嵌套文档,但目前并未支持。

有时你需要完整分离主要文档及其关连实体。 父-子关系提供这一个功能。