IP range aggregation
Just like the dedicated date range aggregation, there is also a dedicated range aggregation for IP typed fields:
Example:
resp = client.search(
index="ip_addresses",
size=10,
aggs={
"ip_ranges": {
"ip_range": {
"field": "ip",
"ranges": [
{
"to": "10.0.0.5"
},
{
"from": "10.0.0.5"
}
]
}
}
},
)
print(resp) response = client.search(
index: 'ip_addresses',
body: {
size: 10,
aggregations: {
ip_ranges: {
ip_range: {
field: 'ip',
ranges: [
{
to: '10.0.0.5'
},
{
from: '10.0.0.5'
}
]
}
}
}
}
)
puts response const response = await client.search({
index: "ip_addresses",
size: 10,
aggs: {
ip_ranges: {
ip_range: {
field: "ip",
ranges: [
{
to: "10.0.0.5",
},
{
from: "10.0.0.5",
},
],
},
},
},
});
console.log(response); GET /ip_addresses/_search
{
"size": 10,
"aggs": {
"ip_ranges": {
"ip_range": {
"field": "ip",
"ranges": [
{ "to": "10.0.0.5" },
{ "from": "10.0.0.5" }
]
}
}
}
} Response:
{
...
"aggregations": {
"ip_ranges": {
"buckets": [
{
"key": "*-10.0.0.5",
"to": "10.0.0.5",
"doc_count": 10
},
{
"key": "10.0.0.5-*",
"from": "10.0.0.5",
"doc_count": 260
}
]
}
}
} IP ranges can also be defined as CIDR masks:
resp = client.search(
index="ip_addresses",
size=0,
aggs={
"ip_ranges": {
"ip_range": {
"field": "ip",
"ranges": [
{
"mask": "10.0.0.0/25"
},
{
"mask": "10.0.0.127/25"
}
]
}
}
},
)
print(resp) response = client.search(
index: 'ip_addresses',
body: {
size: 0,
aggregations: {
ip_ranges: {
ip_range: {
field: 'ip',
ranges: [
{
mask: '10.0.0.0/25'
},
{
mask: '10.0.0.127/25'
}
]
}
}
}
}
)
puts response const response = await client.search({
index: "ip_addresses",
size: 0,
aggs: {
ip_ranges: {
ip_range: {
field: "ip",
ranges: [
{
mask: "10.0.0.0/25",
},
{
mask: "10.0.0.127/25",
},
],
},
},
},
});
console.log(response); GET /ip_addresses/_search
{
"size": 0,
"aggs": {
"ip_ranges": {
"ip_range": {
"field": "ip",
"ranges": [
{ "mask": "10.0.0.0/25" },
{ "mask": "10.0.0.127/25" }
]
}
}
}
} Response:
{
...
"aggregations": {
"ip_ranges": {
"buckets": [
{
"key": "10.0.0.0/25",
"from": "10.0.0.0",
"to": "10.0.0.128",
"doc_count": 128
},
{
"key": "10.0.0.127/25",
"from": "10.0.0.0",
"to": "10.0.0.128",
"doc_count": 128
}
]
}
}
} Keyed Response
Setting the keyed flag to true will associate a unique string key with each bucket and return the ranges as a hash rather than an array:
resp = client.search(
index="ip_addresses",
size=0,
aggs={
"ip_ranges": {
"ip_range": {
"field": "ip",
"ranges": [
{
"to": "10.0.0.5"
},
{
"from": "10.0.0.5"
}
],
"keyed": True
}
}
},
)
print(resp) response = client.search(
index: 'ip_addresses',
body: {
size: 0,
aggregations: {
ip_ranges: {
ip_range: {
field: 'ip',
ranges: [
{
to: '10.0.0.5'
},
{
from: '10.0.0.5'
}
],
keyed: true
}
}
}
}
)
puts response const response = await client.search({
index: "ip_addresses",
size: 0,
aggs: {
ip_ranges: {
ip_range: {
field: "ip",
ranges: [
{
to: "10.0.0.5",
},
{
from: "10.0.0.5",
},
],
keyed: true,
},
},
},
});
console.log(response); GET /ip_addresses/_search
{
"size": 0,
"aggs": {
"ip_ranges": {
"ip_range": {
"field": "ip",
"ranges": [
{ "to": "10.0.0.5" },
{ "from": "10.0.0.5" }
],
"keyed": true
}
}
}
} Response:
{
...
"aggregations": {
"ip_ranges": {
"buckets": {
"*-10.0.0.5": {
"to": "10.0.0.5",
"doc_count": 10
},
"10.0.0.5-*": {
"from": "10.0.0.5",
"doc_count": 260
}
}
}
}
} It is also possible to customize the key for each range:
resp = client.search(
index="ip_addresses",
size=0,
aggs={
"ip_ranges": {
"ip_range": {
"field": "ip",
"ranges": [
{
"key": "infinity",
"to": "10.0.0.5"
},
{
"key": "and-beyond",
"from": "10.0.0.5"
}
],
"keyed": True
}
}
},
)
print(resp) response = client.search(
index: 'ip_addresses',
body: {
size: 0,
aggregations: {
ip_ranges: {
ip_range: {
field: 'ip',
ranges: [
{
key: 'infinity',
to: '10.0.0.5'
},
{
key: 'and-beyond',
from: '10.0.0.5'
}
],
keyed: true
}
}
}
}
)
puts response const response = await client.search({
index: "ip_addresses",
size: 0,
aggs: {
ip_ranges: {
ip_range: {
field: "ip",
ranges: [
{
key: "infinity",
to: "10.0.0.5",
},
{
key: "and-beyond",
from: "10.0.0.5",
},
],
keyed: true,
},
},
},
});
console.log(response); GET /ip_addresses/_search
{
"size": 0,
"aggs": {
"ip_ranges": {
"ip_range": {
"field": "ip",
"ranges": [
{ "key": "infinity", "to": "10.0.0.5" },
{ "key": "and-beyond", "from": "10.0.0.5" }
],
"keyed": true
}
}
}
} Response:
{
...
"aggregations": {
"ip_ranges": {
"buckets": {
"infinity": {
"to": "10.0.0.5",
"doc_count": 10
},
"and-beyond": {
"from": "10.0.0.5",
"doc_count": 260
}
}
}
}
}
© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/8.17/search-aggregations-bucket-iprange-aggregation.html