Link Search Menu Expand Document Documentation Menu

Children

The children aggregation is a bucket aggregation that creates a single bucket containing child documents, based on parent-child relationships defined in your index.

The children aggregation works with the join field type to aggregate child documents that are associated with parent documents.

The children aggregation identifies child documents that match specific child relation name, whereas the parent aggregation identifies parent documents that have matching child documents. Both aggregations take the child relation name as input.

Parameters

The children aggregation takes the following parameters.

Parameter Required/Optional Data type Description
type Required String The name of the child type from the join field. This identifies the parent-child relationship to use.

Example

The following example builds a small company database with three employees. The employee records each have a child join relationship with a parent department record.

First, create a company index with a join field that maps departments (parents) to employees (children):

PUT /company
{
  "mappings": {
    "properties": {
      "join_field": {
        "type": "join",
        "relations": {
          "department": "employee"
        }
      },
      "department_name": {
        "type": "keyword"
      },
      "employee_name": {
        "type": "keyword"
      },
      "salary": {
        "type": "double"
      },
      "hire_date": {
        "type": "date"
      }
    }
  }
}

Next, populate the data with three departments and three employees. The parent-child assignments are presented in the following table.

Department (parent) Employees (children)
Accounting Abel Anderson, Betty Billings
Engineering Carl Carter
HR none

The routing parameter ensures that both parent and child documents are stored on the same shard, which is required in order for parent-child relationships to function correctly in OpenSearch:

POST _bulk?routing=1
{ "create": { "_index": "company", "_id": "1" } }
{ "type": "department", "department_name": "Accounting", "join_field": "department" }
{ "create": { "_index": "company", "_id": "2" } }
{ "type": "department", "department_name": "Engineering", "join_field": "department" }
{ "create": { "_index": "company", "_id": "3" } }
{ "type": "department", "department_name": "HR", "join_field": "department" }
{ "create": { "_index": "company", "_id": "4" } }
{ "type": "employee", "employee_name": "Abel Anderson", "salary": 120000, "hire_date": "2024-04-04", "join_field": { "name": "employee",  "parent": "1" } }
{ "create": { "_index": "company", "_id": "5" } }
{ "type": "employee", "employee_name": "Betty Billings", "salary": 140000, "hire_date": "2023-05-05", "join_field": { "name": "employee",  "parent": "1" } }
{ "create": { "_index": "company", "_id": "6" } }
{ "type": "employee", "employee_name": "Carl Carter", "salary": 140000, "hire_date": "2020-06-06",  "join_field": { "name": "employee",  "parent": "2" } }

The following request queries all the departments and then filters for the one named Accounting. It then uses the children aggregation to select the two documents that have a child relationship with the Accounting department. Finally, the avg subaggregation returns the average of the Accounting employees’ salaries:

GET /company/_search
{
  "size": 0,
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "join_field": "department"
          }
        },
        {
          "term": {
            "department_name": "Accounting"
          }
        }
      ]
    }
  },
  "aggs": {
    "acc_employees": {
      "children": {
        "type": "employee"
      },
      "aggs": {
        "avg_salary": {
          "avg": {
            "field": "salary"
          }
        }
      }
    }
  }
}

Example response

The response returns the selected department bucket, finds the employee type children of the department, and computes the avg of their salaries:

{
  "took": 379,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": null,
    "hits": []
  },
  "aggregations": {
    "acc_employees": {
      "doc_count": 2,
      "avg_salary": {
        "value": 110000
      }
    }
  }
}
350 characters left

Have a question? .

Want to contribute? or .