IP 前缀聚合编辑

一种桶聚合,根据 IP 地址的网络或子网对文档进行分组。IP 地址由两组位组成:表示网络前缀的最高有效位和表示主机的最低有效位。

示例编辑

例如,考虑以下索引

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
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 的网络掩码应用于 ipv4 字段中的每个 IP 地址来计算的

response = client.search(
  index: 'network-traffic',
  body: {
    size: 0,
    aggregations: {
      "ipv4-subnets": {
        ip_prefix: {
          field: 'ipv4',
          prefix_length: 24
        }
      }
    }
  }
)
puts 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

response = client.search(
  index: 'network-traffic',
  body: {
    size: 0,
    aggregations: {
      "ipv6-subnets": {
        ip_prefix: {
          field: 'ipv6',
          prefix_length: 64,
          "is_ipv6": true
        }
      }
    }
  }
)
puts response
GET /network-traffic/_search
{
  "size": 0,
  "aggs": {
    "ipv6-subnets": {
      "ip_prefix": {
        "field": "ipv6",
        "prefix_length": 64,
        "is_ipv6": true
      }
    }
  }
}

如果 is_ipv6true,则响应不包含每个桶的 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_ipv6true,则响应中缺少此字段。

键控响应编辑

keyed 标志设置为 true 以将唯一的 IP 地址键与每个桶相关联,并将子网作为哈希表而不是数组返回。

示例

response = client.search(
  index: 'network-traffic',
  body: {
    size: 0,
    aggregations: {
      "ipv4-subnets": {
        ip_prefix: {
          field: 'ipv4',
          prefix_length: 24,
          keyed: true
        }
      }
    }
  }
)
puts 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 地址键与子网的前缀长度连接起来。

示例

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
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 参数仅返回具有最小文档数的桶。

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
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"
        }
      ]
    }
  }
}