Агрегирование по префиксу IP-адреса
Агрегация по корзинам, группирующая документы по сети или подсети IP-адреса. IP-адрес состоит из двух групп битов: наиболее значимые биты представляют префикс сети, а наименее значимые биты — хост.
Пример
Например, рассмотрим следующий индекс:
resp = client.indices.create(
index="network-traffic",
mappings={
"properties": {
"ipv4": {
"type": "ip"
},
"ipv6": {
"type": "ip"
}
}
},
)
print(resp)
resp1 = client.bulk(
index="network-traffic",
refresh=True,
operations=[
{
"index": {
"_id": 0
}
},
{
"ipv4": "192.168.1.10",
"ipv6": "2001:db8:a4f8:112a:6001:0:12:7f10"
},
{
"index": {
"_id": 1
}
},
{
"ipv4": "192.168.1.12",
"ipv6": "2001:db8:a4f8:112a:6001:0:12:7f12"
},
{
"index": {
"_id": 2
}
},
{
"ipv4": "192.168.1.33",
"ipv6": "2001:db8:a4f8:112a:6001:0:12:7f33"
},
{
"index": {
"_id": 3
}
},
{
"ipv4": "192.168.1.10",
"ipv6": "2001:db8:a4f8:112a:6001:0:12:7f10"
},
{
"index": {
"_id": 4
}
},
{
"ipv4": "192.168.2.41",
"ipv6": "2001:db8:a4f8:112c:6001:0:12:7f41"
},
{
"index": {
"_id": 5
}
},
{
"ipv4": "192.168.2.10",
"ipv6": "2001:db8:a4f8:112c:6001:0:12:7f10"
},
{
"index": {
"_id": 6
}
},
{
"ipv4": "192.168.2.23",
"ipv6": "2001:db8:a4f8:112c:6001:0:12:7f23"
},
{
"index": {
"_id": 7
}
},
{
"ipv4": "192.168.3.201",
"ipv6": "2001:db8:a4f8:114f:6001:0:12:7201"
},
{
"index": {
"_id": 8
}
},
{
"ipv4": "192.168.3.107",
"ipv6": "2001:db8:a4f8:114f:6001:0:12:7307"
}
],
)
print(resp1) response = client.indices.create(
index: 'network-traffic',
body: {
mappings: {
properties: {
"ipv4": {
type: 'ip'
},
"ipv6": {
type: 'ip'
}
}
}
}
)
puts response
response = client.bulk(
index: 'network-traffic',
refresh: true,
body: [
{
index: {
_id: 0
}
},
{
"ipv4": '192.168.1.10',
"ipv6": '2001:db8:a4f8:112a:6001:0:12:7f10'
},
{
index: {
_id: 1
}
},
{
"ipv4": '192.168.1.12',
"ipv6": '2001:db8:a4f8:112a:6001:0:12:7f12'
},
{
index: {
_id: 2
}
},
{
"ipv4": '192.168.1.33',
"ipv6": '2001:db8:a4f8:112a:6001:0:12:7f33'
},
{
index: {
_id: 3
}
},
{
"ipv4": '192.168.1.10',
"ipv6": '2001:db8:a4f8:112a:6001:0:12:7f10'
},
{
index: {
_id: 4
}
},
{
"ipv4": '192.168.2.41',
"ipv6": '2001:db8:a4f8:112c:6001:0:12:7f41'
},
{
index: {
_id: 5
}
},
{
"ipv4": '192.168.2.10',
"ipv6": '2001:db8:a4f8:112c:6001:0:12:7f10'
},
{
index: {
_id: 6
}
},
{
"ipv4": '192.168.2.23',
"ipv6": '2001:db8:a4f8:112c:6001:0:12:7f23'
},
{
index: {
_id: 7
}
},
{
"ipv4": '192.168.3.201',
"ipv6": '2001:db8:a4f8:114f:6001:0:12:7201'
},
{
index: {
_id: 8
}
},
{
"ipv4": '192.168.3.107',
"ipv6": '2001:db8:a4f8:114f:6001:0:12:7307'
}
]
)
puts response const response = await client.indices.create({
index: "network-traffic",
mappings: {
properties: {
ipv4: {
type: "ip",
},
ipv6: {
type: "ip",
},
},
},
});
console.log(response);
const response1 = await client.bulk({
index: "network-traffic",
refresh: "true",
operations: [
{
index: {
_id: 0,
},
},
{
ipv4: "192.168.1.10",
ipv6: "2001:db8:a4f8:112a:6001:0:12:7f10",
},
{
index: {
_id: 1,
},
},
{
ipv4: "192.168.1.12",
ipv6: "2001:db8:a4f8:112a:6001:0:12:7f12",
},
{
index: {
_id: 2,
},
},
{
ipv4: "192.168.1.33",
ipv6: "2001:db8:a4f8:112a:6001:0:12:7f33",
},
{
index: {
_id: 3,
},
},
{
ipv4: "192.168.1.10",
ipv6: "2001:db8:a4f8:112a:6001:0:12:7f10",
},
{
index: {
_id: 4,
},
},
{
ipv4: "192.168.2.41",
ipv6: "2001:db8:a4f8:112c:6001:0:12:7f41",
},
{
index: {
_id: 5,
},
},
{
ipv4: "192.168.2.10",
ipv6: "2001:db8:a4f8:112c:6001:0:12:7f10",
},
{
index: {
_id: 6,
},
},
{
ipv4: "192.168.2.23",
ipv6: "2001:db8:a4f8:112c:6001:0:12:7f23",
},
{
index: {
_id: 7,
},
},
{
ipv4: "192.168.3.201",
ipv6: "2001:db8:a4f8:114f:6001:0:12:7201",
},
{
index: {
_id: 8,
},
},
{
ipv4: "192.168.3.107",
ipv6: "2001:db8:a4f8:114f:6001:0:12:7307",
},
],
});
console.log(response1); PUT network-traffic
{
"mappings": {
"properties": {
"ipv4": { "type": "ip" },
"ipv6": { "type": "ip" }
}
}
}
POST /network-traffic/_bulk?refresh
{"index":{"_id":0}}
{"ipv4":"192.168.1.10","ipv6":"2001:db8:a4f8:112a:6001:0:12:7f10"}
{"index":{"_id":1}}
{"ipv4":"192.168.1.12","ipv6":"2001:db8:a4f8:112a:6001:0:12:7f12"}
{"index":{"_id":2}}
{ "ipv4":"192.168.1.33","ipv6":"2001:db8:a4f8:112a:6001:0:12:7f33"}
{"index":{"_id":3}}
{"ipv4":"192.168.1.10","ipv6":"2001:db8:a4f8:112a:6001:0:12:7f10"}
{"index":{"_id":4}}
{"ipv4":"192.168.2.41","ipv6":"2001:db8:a4f8:112c:6001:0:12:7f41"}
{"index":{"_id":5}}
{"ipv4":"192.168.2.10","ipv6":"2001:db8:a4f8:112c:6001:0:12:7f10"}
{"index":{"_id":6}}
{"ipv4":"192.168.2.23","ipv6":"2001:db8:a4f8:112c:6001:0:12:7f23"}
{"index":{"_id":7}}
{"ipv4":"192.168.3.201","ipv6":"2001:db8:a4f8:114f:6001:0:12:7201"}
{"index":{"_id":8}}
{"ipv4":"192.168.3.107","ipv6":"2001:db8:a4f8:114f:6001:0:12:7307"} Следующая агрегация группирует документы в корзины. Каждая корзина идентифицирует разную подсеть. Подсеть вычисляется путем применения маски сети с длиной префикса 24 к каждому IP-адресу в поле ipv4:
resp = client.search(
index="network-traffic",
size=0,
aggs={
"ipv4-subnets": {
"ip_prefix": {
"field": "ipv4",
"prefix_length": 24
}
}
},
)
print(resp) response = client.search(
index: 'network-traffic',
body: {
size: 0,
aggregations: {
"ipv4-subnets": {
ip_prefix: {
field: 'ipv4',
prefix_length: 24
}
}
}
}
)
puts response const response = await client.search({
index: "network-traffic",
size: 0,
aggs: {
"ipv4-subnets": {
ip_prefix: {
field: "ipv4",
prefix_length: 24,
},
},
},
});
console.log(response); GET /network-traffic/_search
{
"size": 0,
"aggs": {
"ipv4-subnets": {
"ip_prefix": {
"field": "ipv4",
"prefix_length": 24
}
}
}
} Ответ:
{
...
"aggregations": {
"ipv4-subnets": {
"buckets": [
{
"key": "192.168.1.0",
"is_ipv6": false,
"doc_count": 4,
"prefix_length": 24,
"netmask": "255.255.255.0"
},
{
"key": "192.168.2.0",
"is_ipv6": false,
"doc_count": 3,
"prefix_length": 24,
"netmask": "255.255.255.0"
},
{
"key": "192.168.3.0",
"is_ipv6": false,
"doc_count": 2,
"prefix_length": 24,
"netmask": "255.255.255.0"
}
]
}
}
} Для агрегирования IPv6-адресов установите is_ipv6 в значение true.
resp = client.search(
index="network-traffic",
size=0,
aggs={
"ipv6-subnets": {
"ip_prefix": {
"field": "ipv6",
"prefix_length": 64,
"is_ipv6": True
}
}
},
)
print(resp) response = client.search(
index: 'network-traffic',
body: {
size: 0,
aggregations: {
"ipv6-subnets": {
ip_prefix: {
field: 'ipv6',
prefix_length: 64,
"is_ipv6": true
}
}
}
}
)
puts response const response = await client.search({
index: "network-traffic",
size: 0,
aggs: {
"ipv6-subnets": {
ip_prefix: {
field: "ipv6",
prefix_length: 64,
is_ipv6: true,
},
},
},
});
console.log(response); GET /network-traffic/_search
{
"size": 0,
"aggs": {
"ipv6-subnets": {
"ip_prefix": {
"field": "ipv6",
"prefix_length": 64,
"is_ipv6": true
}
}
}
} Если is_ipv6 равно true, ответ не включает netmask для каждой корзины.
{
...
"aggregations": {
"ipv6-subnets": {
"buckets": [
{
"key": "2001:db8:a4f8:112a::",
"is_ipv6": true,
"doc_count": 4,
"prefix_length": 64
},
{
"key": "2001:db8:a4f8:112c::",
"is_ipv6": true,
"doc_count": 3,
"prefix_length": 64
},
{
"key": "2001:db8:a4f8:114f::",
"is_ipv6": true,
"doc_count": 2,
"prefix_length": 64
}
]
}
}
} Параметры
-
field - (Обязательно, строка) Поле IP-адреса документа, по которому выполняется агрегирование. Тип отображения поля должен быть
ip. -
prefix_length - (Обязательно, целое число) Длина префикса сети. Для IPv4-адресов допустимый диапазон —
[0, 32]. Для IPv6-адресов допустимый диапазон —[0, 128]. -
is_ipv6 - (Необязательно, логическое значение) Определяет, относится ли префикс к IPv6-адресам. Просто указание параметра
prefix_lengthнедостаточно для определения, относится ли префикс IP к IPv4 или IPv6-адресам. Значение по умолчанию —false. -
append_prefix_length - (Необязательно, логическое значение) Определяет, добавляется ли длина префикса к ключам IP-адресов в ответе. Значение по умолчанию —
false. -
keyed - (Необязательно, логическое значение) Определяет, возвращаются ли корзины в виде хэша, а не массива в ответе. Значение по умолчанию —
false. -
min_doc_count - (Необязательно, целое число) Определяет минимальное количество документов для включения корзин в ответ. Значение по умолчанию —
1.
Тело ответа
-
key - (строка) Подсеть IPv6 или IPv4.
-
prefix_length - (целое число) Длина префикса, используемого для агрегирования корзины.
-
doc_count - (целое число) Количество документов, соответствующих определенному префиксу IP-адреса.
-
is_ipv6 - (логическое значение) Определяет, является ли маска сети маской IPv6.
-
netmask - (строка) Маска сети IPv4. Если
is_ipv6равноtrueв запросе, это поле отсутствует в ответе.
Ответ с ключами
Установите флаг keyed параметра true, чтобы присвоить уникальный ключ IP-адреса каждой корзине и вернуть подсети в виде хэша, а не массива.
Пример:
resp = client.search(
index="network-traffic",
size=0,
aggs={
"ipv4-subnets": {
"ip_prefix": {
"field": "ipv4",
"prefix_length": 24,
"keyed": True
}
}
},
)
print(resp) response = client.search(
index: 'network-traffic',
body: {
size: 0,
aggregations: {
"ipv4-subnets": {
ip_prefix: {
field: 'ipv4',
prefix_length: 24,
keyed: true
}
}
}
}
)
puts response const response = await client.search({
index: "network-traffic",
size: 0,
aggs: {
"ipv4-subnets": {
ip_prefix: {
field: "ipv4",
prefix_length: 24,
keyed: true,
},
},
},
});
console.log(response); GET /network-traffic/_search
{
"size": 0,
"aggs": {
"ipv4-subnets": {
"ip_prefix": {
"field": "ipv4",
"prefix_length": 24,
"keyed": true
}
}
}
} Ответ:
{
...
"aggregations": {
"ipv4-subnets": {
"buckets": {
"192.168.1.0": {
"is_ipv6": false,
"doc_count": 4,
"prefix_length": 24,
"netmask": "255.255.255.0"
},
"192.168.2.0": {
"is_ipv6": false,
"doc_count": 3,
"prefix_length": 24,
"netmask": "255.255.255.0"
},
"192.168.3.0": {
"is_ipv6": false,
"doc_count": 2,
"prefix_length": 24,
"netmask": "255.255.255.0"
}
}
}
}
} Добавление длины префикса к ключу IP-адреса
Установите флаг append_prefix_length в значение true, чтобы конкатенировать ключи IP-адресов с длиной префикса подсети.
Пример:
resp = client.search(
index="network-traffic",
size=0,
aggs={
"ipv4-subnets": {
"ip_prefix": {
"field": "ipv4",
"prefix_length": 24,
"append_prefix_length": True
}
}
},
)
print(resp) response = client.search(
index: 'network-traffic',
body: {
size: 0,
aggregations: {
"ipv4-subnets": {
ip_prefix: {
field: 'ipv4',
prefix_length: 24,
append_prefix_length: true
}
}
}
}
)
puts response const response = await client.search({
index: "network-traffic",
size: 0,
aggs: {
"ipv4-subnets": {
ip_prefix: {
field: "ipv4",
prefix_length: 24,
append_prefix_length: true,
},
},
},
});
console.log(response); GET /network-traffic/_search
{
"size": 0,
"aggs": {
"ipv4-subnets": {
"ip_prefix": {
"field": "ipv4",
"prefix_length": 24,
"append_prefix_length": true
}
}
}
} Ответ:
{
...
"aggregations": {
"ipv4-subnets": {
"buckets": [
{
"key": "192.168.1.0/24",
"is_ipv6": false,
"doc_count": 4,
"prefix_length": 24,
"netmask": "255.255.255.0"
},
{
"key": "192.168.2.0/24",
"is_ipv6": false,
"doc_count": 3,
"prefix_length": 24,
"netmask": "255.255.255.0"
},
{
"key": "192.168.3.0/24",
"is_ipv6": false,
"doc_count": 2,
"prefix_length": 24,
"netmask": "255.255.255.0"
}
]
}
}
} Минимальное количество документов
Используйте параметр min_doc_count, чтобы возвращать только корзины с минимальным количеством документов.
resp = client.search(
index="network-traffic",
size=0,
aggs={
"ipv4-subnets": {
"ip_prefix": {
"field": "ipv4",
"prefix_length": 24,
"min_doc_count": 3
}
}
},
)
print(resp) response = client.search(
index: 'network-traffic',
body: {
size: 0,
aggregations: {
"ipv4-subnets": {
ip_prefix: {
field: 'ipv4',
prefix_length: 24,
min_doc_count: 3
}
}
}
}
)
puts response const response = await client.search({
index: "network-traffic",
size: 0,
aggs: {
"ipv4-subnets": {
ip_prefix: {
field: "ipv4",
prefix_length: 24,
min_doc_count: 3,
},
},
},
});
console.log(response); GET /network-traffic/_search
{
"size": 0,
"aggs": {
"ipv4-subnets": {
"ip_prefix": {
"field": "ipv4",
"prefix_length": 24,
"min_doc_count": 3
}
}
}
} Ответ:
{
...
"aggregations": {
"ipv4-subnets": {
"buckets": [
{
"key": "192.168.1.0",
"is_ipv6": false,
"doc_count": 4,
"prefix_length": 24,
"netmask": "255.255.255.0"
},
{
"key": "192.168.2.0",
"is_ipv6": false,
"doc_count": 3,
"prefix_length": 24,
"netmask": "255.255.255.0"
}
]
}
}
}
© 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-ipprefix-aggregation.html