Link Search Menu Expand Document Documentation Menu

Parent aggregations

The parent aggregation is a bucket aggregation that creates a single bucket containing parent documents, based on parent-child relationships defined in your index. This aggregation enables you to perform analytics on parent documents that have the same matching child documents, allowing for powerful hierarchical data analysis.

The parent aggregation works with the join field type, which establishes parent-child relationships within documents in the same index.

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

Parameters

The parent aggregation takes the following parameters:

Parameter Required/Optional Data type Description
type Required String The name of the child type from the join field.

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" } }

Lastly, run an aggregation of all the departments that have a parent relationship with one or more employees:

GET /company/_search
{
  "size": 0,
  "aggs": {
    "all_departments": {
      "parent": {
        "type": "employee"
      },
      "aggs": {
        "departments": {
          "terms": {
            "field": "department_name"
          }
        }
      }
    }
  }
}

Example response

The all_departments parent aggregation returns all the departments with employee child documents. Note that the HR department is not represented:

{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 6,
      "relation": "eq"
    },
    "max_score": null,
    "hits": []
  },
  "aggregations": {
    "all_departments": {
      "doc_count": 2,
      "departments": {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 0,
        "buckets": [
          {
            "key": "Accounting",
            "doc_count": 1
          },
          {
            "key": "Engineering",
            "doc_count": 1
          }
        ]
      }
    }
  }
}
350 characters left

Have a question? .

Want to contribute? or .