逆ネスト集約

親ドキュメントからネストされたドキュメントを集約する特別な単一バケット集約です。この集約は、ネストされたブロック構造から抜け出し、他のネストされた構造やルートドキュメントにリンクすることができ、ネストされた集約の一部ではない他の集約をネストすることを可能にします。

reverse_nested 集約は nested 集約の内部で定義する必要があります。

オプション:

  • path - どのネストされたオブジェクトフィールドに戻るべきかを定義します。デフォルトは空で、これはルート/メインドキュメントレベルに戻ることを意味します。パスは nested 集約のネストされた構造の外にあるネストされたオブジェクトフィールドへの参照を含むことはできません。reverse_nested の中にあります。

例えば、問題とコメントを持つチケットシステムのインデックスがあるとしましょう。コメントはネストされたドキュメントとして問題ドキュメントにインラインで含まれています。マッピングは次のようになります:

Python

  1. resp = client.indices.create(
  2. index="issues",
  3. mappings={
  4. "properties": {
  5. "tags": {
  6. "type": "keyword"
  7. },
  8. "comments": {
  9. "type": "nested",
  10. "properties": {
  11. "username": {
  12. "type": "keyword"
  13. },
  14. "comment": {
  15. "type": "text"
  16. }
  17. }
  18. }
  19. }
  20. },
  21. )
  22. print(resp)

Ruby

  1. response = client.indices.create(
  2. index: 'issues',
  3. body: {
  4. mappings: {
  5. properties: {
  6. tags: {
  7. type: 'keyword'
  8. },
  9. comments: {
  10. type: 'nested',
  11. properties: {
  12. username: {
  13. type: 'keyword'
  14. },
  15. comment: {
  16. type: 'text'
  17. }
  18. }
  19. }
  20. }
  21. }
  22. }
  23. )
  24. puts response

Js

  1. const response = await client.indices.create({
  2. index: "issues",
  3. mappings: {
  4. properties: {
  5. tags: {
  6. type: "keyword",
  7. },
  8. comments: {
  9. type: "nested",
  10. properties: {
  11. username: {
  12. type: "keyword",
  13. },
  14. comment: {
  15. type: "text",
  16. },
  17. },
  18. },
  19. },
  20. },
  21. });
  22. console.log(response);

コンソール

  1. PUT /issues
  2. {
  3. "mappings": {
  4. "properties": {
  5. "tags": { "type": "keyword" },
  6. "comments": {
  7. "type": "nested",
  8. "properties": {
  9. "username": { "type": "keyword" },
  10. "comment": { "type": "text" }
  11. }
  12. }
  13. }
  14. }
  15. }
commentsissue オブジェクトの下にネストされたドキュメントを保持する配列です。

次の集約は、コメントしたトップコメント者のユーザー名と、ユーザーがコメントした問題のトップタグを返します:

Python

  1. resp = client.search(
  2. index="issues",
  3. query={
  4. "match_all": {}
  5. },
  6. aggs={
  7. "comments": {
  8. "nested": {
  9. "path": "comments"
  10. },
  11. "aggs": {
  12. "top_usernames": {
  13. "terms": {
  14. "field": "comments.username"
  15. },
  16. "aggs": {
  17. "comment_to_issue": {
  18. "reverse_nested": {},
  19. "aggs": {
  20. "top_tags_per_comment": {
  21. "terms": {
  22. "field": "tags"
  23. }
  24. }
  25. }
  26. }
  27. }
  28. }
  29. }
  30. }
  31. },
  32. )
  33. print(resp)

Ruby

  1. response = client.search(
  2. index: 'issues',
  3. body: {
  4. query: {
  5. match_all: {}
  6. },
  7. aggregations: {
  8. comments: {
  9. nested: {
  10. path: 'comments'
  11. },
  12. aggregations: {
  13. top_usernames: {
  14. terms: {
  15. field: 'comments.username'
  16. },
  17. aggregations: {
  18. comment_to_issue: {
  19. reverse_nested: {},
  20. aggregations: {
  21. top_tags_per_comment: {
  22. terms: {
  23. field: 'tags'
  24. }
  25. }
  26. }
  27. }
  28. }
  29. }
  30. }
  31. }
  32. }
  33. }
  34. )
  35. puts response

Js

  1. const response = await client.search({
  2. index: "issues",
  3. query: {
  4. match_all: {},
  5. },
  6. aggs: {
  7. comments: {
  8. nested: {
  9. path: "comments",
  10. },
  11. aggs: {
  12. top_usernames: {
  13. terms: {
  14. field: "comments.username",
  15. },
  16. aggs: {
  17. comment_to_issue: {
  18. reverse_nested: {},
  19. aggs: {
  20. top_tags_per_comment: {
  21. terms: {
  22. field: "tags",
  23. },
  24. },
  25. },
  26. },
  27. },
  28. },
  29. },
  30. },
  31. },
  32. });
  33. console.log(response);

コンソール

  1. GET /issues/_search
  2. {
  3. "query": {
  4. "match_all": {}
  5. },
  6. "aggs": {
  7. "comments": {
  8. "nested": {
  9. "path": "comments"
  10. },
  11. "aggs": {
  12. "top_usernames": {
  13. "terms": {
  14. "field": "comments.username"
  15. },
  16. "aggs": {
  17. "comment_to_issue": {
  18. "reverse_nested": {},
  19. "aggs": {
  20. "top_tags_per_comment": {
  21. "terms": {
  22. "field": "tags"
  23. }
  24. }
  25. }
  26. }
  27. }
  28. }
  29. }
  30. }
  31. }
  32. }

上記のように、reverse_nested 集約は nested 集約に配置されており、これは reverse_nested 集約が使用できる唯一の場所です。その唯一の目的は、ネストされた構造の上位にある親ドキュメントに戻ることです。

reverse_nested 集約はルート/メインドキュメントレベルに戻ります。path が定義されていないためです。

path オプションを介して、reverse_nested 集約は、マッピングで複数のレイヤーのネストされたオブジェクトタイプが定義されている場合、異なるレベルに戻ることができます

可能なレスポンススニペット:

コンソール-結果

  1. {
  2. "aggregations": {
  3. "comments": {
  4. "doc_count": 1,
  5. "top_usernames": {
  6. "doc_count_error_upper_bound" : 0,
  7. "sum_other_doc_count" : 0,
  8. "buckets": [
  9. {
  10. "key": "username_1",
  11. "doc_count": 1,
  12. "comment_to_issue": {
  13. "doc_count": 1,
  14. "top_tags_per_comment": {
  15. "doc_count_error_upper_bound" : 0,
  16. "sum_other_doc_count" : 0,
  17. "buckets": [
  18. {
  19. "key": "tag_1",
  20. "doc_count": 1
  21. }
  22. ...
  23. ]
  24. }
  25. }
  26. }
  27. ...
  28. ]
  29. }
  30. }
  31. }
  32. }