在ElasticSearch的IP类型字段中存储CIDR

时间:2017-02-11 16:50:49

标签: elasticsearch

是否可以在弹性搜索中将IP地址数据类型中的CIDR符号存储起来?当我尝试将它们发布到我的索引中时,它会失败。 (单一属性有ip类型)

{
  "singlerange": "222.165.0.0/17",
  "name": "Single range"
}

结果

{
  "error": {
    "root_cause": [
      {
        "type": "mapper_parsing_exception",
        "reason": "failed to parse [singlerange]"
      }
    ],
    "type": "mapper_parsing_exception",
    "reason": "failed to parse [singlerange]",
    "caused_by": {
      "type": "illegal_argument_exception",
      "reason": "'222.165.0.0/17' is not an IP string literal."
    }
  },
  "status": 400
}

所以,ES告诉我'不',但在我放弃使用ES作为工具之前,我想知道是否有人有解决方法或替代存储和查询范围的方法。

我知道文档有用于存储IP和按范围查询的用例。我们的用例相反,我们希望存储范围并查询包含特定IP的任何范围的索引。

1 个答案:

答案 0 :(得分:2)

当然,发布到StackOverflow的行为允许我解决问题。

我所做的是在插入时手动创建范围

{
  "mappings": {
    "newrange": {
      "properties": {
        "bottomrange": {
          "type": "ip"
        },
        "toprange": {
          "type": "ip"
        },
        "name": {
           "type": "text"
        }
      }
    }
  }
}

这允许我插入这样的东西(在这个例子中我代表222.165.0.0/17:

{
  "bottomrange": "222.165.0.1",
  "toprange": "222.165.127.254",
  "name": "Single range"
}

因此我可以使用这样的过滤器进行查询(在这种情况下,尝试查找与222.165.128.99匹配的范围)

{
  "query": { 
    "bool": { 
      "filter": [  
        { "range": { "bottomrange": { "lte": "222.165.128.99" }}} ,
        { "range": { "toprange": { "gte": "222.165.128.99" }}} 
      ]
    }
  }

}

瞧!可能不是最有效的ES查询,但它必须比开发人员将数千个CIDR范围说明符加载到节点内存并迭代每个以进行匹配更高效。我们将看到。