Elasticsearch:IP 数据类型及其搜索

在使用 Elasticsearch 搜索 IP 地址时,我们可以把数据类型定义为 IP  数据类型。这样我们可以针对 IP 地址进行搜索。这种 IP 地址可以是 IPv4 或者是 IPv6 的形式。

现在假设我们导入一个如下的数据到 Elasticsearch 中:

PUT my-index/_doc/1
{
  "ip_addr": "192.168.1.1"
}

在没有定义数据类型的情况下, Elasticsearch 会把上面的字段 ip_add 映射到一个 text  及 keyword 的类型的数据上:

GET my-index/_mapping

上面命令显示的结果为:

{
  "my-index" : {
    "mappings" : {
      "properties" : {
        "ip_addr" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }
}

假如我们想对上面的数据进行如下的搜索:

GET my-index/_search
{
  "query": {
    "term": {
      "ip_addr": "192.168.0.0/16"
    }
  }
}

针对上面的搜索,我稍微做一下解释:对于上面的 IPv4 的 IP 地址含有4个 bytes,而每个 byte 含有8个 digits。在上面的 /16 即表示前面的 16 位的 digits,也即 192.168。我们可以这么说任何一个 IP 地址位于 192.168.0.0 至 192.168.255.255 都在这个范围内。

上面的搜索的结果是:

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}

也就是找不到任何的结果。这是什么原因呢?

就其原因,是因为我们没有正确地把 IP 的数据类型定义为 IP 数据类型。我们重新来定义这个索引的 mapping:

DELETE my-index

PUT my-index
{
  "mappings": {
    "properties": {
      "ip_addr": {
        "type": "ip"
      }
    }
  }
}

PUT my-index/_doc/1
{
  "ip_addr": "192.168.1.1"
}

我们按照上面的步骤来重新建立索引,并导入文档。我们在按照如下的方法来进行搜索:

GET my-index/_search
{
  "query": {
    "term": {
      "ip_addr": "192.168.0.0/16"
    }
  }
}

上面的命令显示的结果为:

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my-index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "ip_addr" : "192.168.1.1"
        }
      }
    ]
  }
}

这次,显然我们搜索到我们需要的文档了,这是因为 192.168.1.1 是属于 IP 地址范围 192.168.0.0/16 的。我们可以通过这样的方法搜索属于一个 IP 范围的日志文件供我们查询。