Children

The children aggregation connects parent documents with their related child documents. This allows you to analyze relationships between different types of data in a single query, rather than needing to run multiple queries and combine the results manually.


Example index, sample data, and children aggregation query

For example, if you have a parent-child relationship between authors, posts, and comments, you can analyze the relationships between the different data types (authors, posts, and comments) in a single query.

The authors aggregation groups the documents by the author.keyword field. This allows you to see the number of documents associates with each author.

In each author group, the children aggregation retrieves the associated posts. This gives you a breakdown of the posts written by each author.

In the posts aggregation, another children aggregation fetches the comments associated with each post. This provides you a way to see the comments for each individual post.

In the comments aggregation, the value_count aggregation counts the number of comments on each post. This allows you to gauge the engagement level for each post by seeing the number of comments it has received.

Example index

  1. PUT /blog-sample
  2. {
  3. "mappings": {
  4. "properties": {
  5. "type": { "type": "keyword" },
  6. "name": { "type": "keyword" },
  7. "title": { "type": "text" },
  8. "content": { "type": "text" },
  9. "author": { "type": "keyword" },
  10. "post_id": { "type": "keyword" },
  11. "join_field": {
  12. "type": "join",
  13. "relations": {
  14. "author": "post",
  15. "post": "comment"
  16. }
  17. }
  18. }
  19. }
  20. }

copy

Sample documents

  1. POST /blog-sample/_doc/1?routing=1
  2. {
  3. "type": "author",
  4. "name": "John Doe",
  5. "join_field": "author"
  6. }
  7. POST /blog-sample/_doc/2?routing=1
  8. {
  9. "type": "post",
  10. "title": "Introduction to OpenSearch",
  11. "content": "OpenSearch is a powerful search and analytics engine...",
  12. "author": "John Doe",
  13. "join_field": {
  14. "name": "post",
  15. "parent": "1"
  16. }
  17. }
  18. POST /blog-sample/_doc/3?routing=1
  19. {
  20. "type": "comment",
  21. "content": "Great article! Very informative.",
  22. "join_field": {
  23. "name": "comment",
  24. "parent": "2"
  25. }
  26. }
  27. POST /blog-sample/_doc/4?routing=1
  28. {
  29. "type": "comment",
  30. "content": "Thanks for the clear explanation.",
  31. "join_field": {
  32. "name": "comment",
  33. "parent": "2"
  34. }
  35. }

copy

Example children aggregation query

  1. GET /blog-sample/_search
  2. {
  3. "size": 0,
  4. "aggs": {
  5. "authors": {
  6. "terms": {
  7. "field": "name.keyword"
  8. },
  9. "aggs": {
  10. "posts": {
  11. "children": {
  12. "type": "post"
  13. },
  14. "aggs": {
  15. "post_titles": {
  16. "terms": {
  17. "field": "title.keyword"
  18. },
  19. "aggs": {
  20. "comments": {
  21. "children": {
  22. "type": "comment"
  23. },
  24. "aggs": {
  25. "comment_count": {
  26. "value_count": {
  27. "field": "_id"
  28. }
  29. }
  30. }
  31. }
  32. }
  33. }
  34. }
  35. }
  36. }
  37. }
  38. }
  39. }

copy

Example response

The response should appear similar to the following example:

  1. {
  2. "took": 30,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 4,
  13. "relation": "eq"
  14. },
  15. "max_score": null,
  16. "hits": []
  17. },
  18. "aggregations": {
  19. "authors": {
  20. "doc_count_error_upper_bound": 0,
  21. "sum_other_doc_count": 0,
  22. "buckets": []
  23. }
  24. }
  25. }