I have documents in an index that look like this:
{
"foo": null,
"bars": [
{
"baz": "BAZ",
"qux": null,
"bears": [
{
"fruit": "banana"
}
]
}
]
}
I want to aggregate unique values of .bars[].bears[].fruit
with counts for each found value. However, I also only want to count these deep values for documents which match certain conditions on foo
, and for values of bars[]
that match certain conditions on baz
and qux
. I also want to aggregate all documents, ignoring whatever the search query happens to be.
The following query does everything I want to do:
{
"aggs": {
"global": {
"global": {},
"aggs": {
"notFoo": {
"filter": {
"bool": {
"must_not": [
{
"exists": {
"field": "foo"
}
}
]
}
},
"aggs": {
"bars": {
"nested": {
"path": "bars"
},
"aggs": {
"notValueN": {
"filter": {
"bool": {
"filter": [
{
"bool": {
"should": [
{
"terms": {
"bars.baz": [
"value1",
"value2",
"value3"
]
}
},
{
"terms": {
"bars.qux": [
"value4",
"value5",
"value6"
]
}
}
],
"minimum_should_match": 1
}
}
]
}
},
"aggs": {
"bears": {
"nested": {
"path": "bars.bears"
},
"aggs": {
"rules": {
"terms": {
"field": "bars.bears.fruit"
}
}
}
}
}
}
}
}
}
}
}
}
}
}
This query works, but it feels rather large and onerous. In order to get the result I'm looking for out of the response I have to access .aggregations.global.bars.notValueN.bears.fruit.buckets
. Is there a way to flatten this large query? As it stands, this query is very hard to maintain should any additional conditions need to be introduced later.