123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- [[search-aggregations-bucket-nested-aggregation]]
- === Nested aggregation
- ++++
- <titleabbrev>Nested</titleabbrev>
- ++++
- A special single bucket aggregation that enables aggregating nested documents.
- For example, lets say we have an index of products, and each product holds the list of resellers - each having its own
- price for the product. The mapping could look like:
- [source,console,id=nested-aggregation-example]
- ----
- PUT /products
- {
- "mappings": {
- "properties": {
- "resellers": { <1>
- "type": "nested",
- "properties": {
- "reseller": {
- "type": "keyword"
- },
- "price": {
- "type": "double"
- }
- }
- }
- }
- }
- }
- ----
- <1> `resellers` is an array that holds nested documents.
- The following request adds a product with two resellers:
- [source,console]
- ----
- PUT /products/_doc/0?refresh
- {
- "name": "LED TV", <1>
- "resellers": [
- {
- "reseller": "companyA",
- "price": 350
- },
- {
- "reseller": "companyB",
- "price": 500
- }
- ]
- }
- ----
- // TEST[continued]
- <1> We are using a dynamic mapping for the `name` attribute.
- The following request returns the minimum price a product can be purchased for:
- [source,console]
- ----
- GET /products/_search?size=0
- {
- "query": {
- "match": {
- "name": "led tv"
- }
- },
- "aggs": {
- "resellers": {
- "nested": {
- "path": "resellers"
- },
- "aggs": {
- "min_price": {
- "min": {
- "field": "resellers.price"
- }
- }
- }
- }
- }
- }
- ----
- // TEST[s/size=0/size=0&filter_path=aggregations/]
- // TEST[continued]
- As you can see above, the nested aggregation requires the `path` of the nested documents within the top level documents.
- Then one can define any type of aggregation over these nested documents.
- Response:
- [source,console-result]
- ----
- {
- ...
- "aggregations": {
- "resellers": {
- "doc_count": 2,
- "min_price": {
- "value": 350.0
- }
- }
- }
- }
- ----
- // TESTRESPONSE[s/\.\.\.//]
- You can use a <<search-aggregations-bucket-filter-aggregation,`filter`>>
- sub-aggregation to return results for a specific reseller.
- [source,console]
- ----
- GET /products/_search?size=0
- {
- "query": {
- "match": {
- "name": "led tv"
- }
- },
- "aggs": {
- "resellers": {
- "nested": {
- "path": "resellers"
- },
- "aggs": {
- "filter_reseller": {
- "filter": {
- "bool": {
- "filter": [
- {
- "term": {
- "resellers.reseller": "companyB"
- }
- }
- ]
- }
- },
- "aggs": {
- "min_price": {
- "min": {
- "field": "resellers.price"
- }
- }
- }
- }
- }
- }
- }
- }
- ----
- // TEST[s/size=0/size=0&filter_path=aggregations/]
- // TEST[continued]
- The search returns:
- [source,console-result]
- ----
- {
- ...
- "aggregations": {
- "resellers": {
- "doc_count": 2,
- "filter_reseller": {
- "doc_count": 1,
- "min_price": {
- "value": 500.0
- }
- }
- }
- }
- }
- ----
- // TESTRESPONSE[s/\.\.\.//]
|