TL;DR composite aggs behave differently than terms agg when there is an index in the pattern that matches the prefix of the other indices that does NOT have a mapped field matching the aggregated field. They behave the same if the "prefix index" has the field, but it is indexed as the wrong type.
Assume we have the following indices
PUT test_index-0001
{
"mappings": {
"properties": {
"ip": {
"type": "ip"
}
}
}
}
PUT test_index-0002
{
"mappings": {
"properties": {
"ip": {
"type": "ip"
}
}
}
}
PUT test_index-0001/_doc/1
{
"ip": "10.2.1.1"
}
PUT test_index-0002/_doc/1
{
"ip": "10.1.1.2"
}
Lets add a new index that does not have an ip field
PUT test_index-0003
{
"mappings": {
"properties": {
"somefield": {
"type": "ip"
}
}
}
}
Composite aggs behaves as follows (as of 7.5).
GET test_index-0001,test_index-0002,test_index*/_search?size=0
{
"aggs": {
"composite_ips": {
"composite": {
"sources": [
{
"ip": {
"terms": {
"field": "ip"
}
}
}
]
}
}
}
}
>
"aggregations" : {
"composite_ips" : {
"after_key" : {
"ip" : "10.2.1.1"
},
"buckets" : [
{
"key" : {
"ip" : "10.1.1.2"
},
"doc_count" : 1
},
{
"key" : {
"ip" : "10.2.1.1"
},
"doc_count" : 1
}
]
}
}
But if the index that is added is instead:
PUT test_index
{
"mappings": {
"properties": {
"somefield": {
"type": "ip"
}
}
}
}
The following is returned from the same composite agg (image for readability)

Note the difference with a plain terms agg
GET test_index-0001,test_index-0002,test_index*/_search?size=0
{
"aggs": {
"term_ips": {
"terms": {
"field": "ip"
}
}
}
}
>
"aggregations" : {
"term_ips" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "10.1.1.2",
"doc_count" : 1
},
{
"key" : "10.2.1.1",
"doc_count" : 1
}
]
}
}
NOTE: if the test_index has the following mapping, composite aggs and terms behave the SAME (showing raw bytes instead of human readable strings)
DELETE test_index
PUT test_index
{
"mappings": {
"properties": {
"ip": {
"type": "ip"
}
}
}
}
GET test_index-0001,test_index-0002,test_index*/_search?size=0
{
"aggs": {
"term_ips": {
"terms": {
"field": "ip"
}
}
}
}
(image for readability)

Related issues/PRs:
TL;DR
compositeaggs behave differently thantermsagg when there is an index in the pattern that matches the prefix of the other indices that does NOT have a mapped field matching the aggregated field. They behave the same if the "prefix index" has the field, but it is indexed as the wrong type.Assume we have the following indices
Lets add a new index that does not have an
ipfieldComposite aggs behaves as follows (as of 7.5).
But if the index that is added is instead:
The following is returned from the same composite agg (image for readability)

Note the difference with a plain
termsaggNOTE: if the
test_indexhas the following mapping, composite aggs and terms behave the SAME (showing raw bytes instead of human readable strings)(image for readability)

Related issues/PRs: