elasticsearch Elastic/OpenSearch:查询复合IP范围,如123.[16-31].0.*

polhcujo  于 7个月前  发布在  ElasticSearch
关注(0)|答案(1)|浏览(77)

我想运行一个查询,筛选出一个IP地址范围,如123.[16-31].0.*(包括16和31)。

GET _search
{
  "query": {
    "bool": {
      "must": {
        "match_phrase": {
          "somefield": "somevalue"
        }
      },
      "must_not": {
        ... ip filter ...
      }
    }
  }
}

字符串
如何编写must_not部分?
一个似乎可行的解决方案是在must_not中放入16个范围:

"must_not": [
        {
          "range": {
            "host.ip": {
              "gte": "123.16.0.0",
              "lte": "123.16.0.255"
            }
          }
        },
.... same for 17 until 30
        {
          "range": {
            "host.ip": {
              "gte": "123.31.0.0",
              "lte": "123.31.0.255"
            }
          }
        }
      ]


但是需要输入很多东西。我喜欢使用这样的正则表达式:

"must_not": {
        "regexp": {
          "host.ip": "123.(1[6-9]|2[0-9]|30|31).0.*"
        }
      }


但是很明显它在Can only use regexp queries on keyword and text fields - not on [host.ip] which is of type [ip]上失败了。

zu0ti5jz

zu0ti5jz1#

生成16个范围是最快的解决方案。但是,如果您不多次运行此请求,并且更愿意用一些CPU时间换取程序员时间,则可以使用运行时Map将ip字段转换为keyword字段。这样,您将能够像对待任何其他文本字段一样对待此字段。因此,您可以这样做:

DELETE test
PUT test
{
  "mappings": {
    "properties": {
      "host": {
        "properties": {
          "ip": {
            "type": "ip"
          }
        }
      }
    }
  }
}

POST test/_bulk?refresh
{"index":{}}
{"host":{"ip":"123.16.0.1"}}
{"index":{}}
{"host":{"ip":"123.16.1.0"}}
{"index":{}}
{"host":{"ip":"124.16.0.1"}}

POST test/_search
{
  "runtime_mappings": {
    "host.ip_string": {
      "type": "keyword",
      "script": {
        "source": "emit(doc['host.ip'].value);"
      }
    }
  },
  "query": {
    "bool": {
      "must_not": [
        {
          "regexp": {
            "host.ip_string": "123.(1[6-9]|2[0-9]|30|31).0.*"
          }
        }
      ]
    }
  }
}

字符串
或者更好的是这样的:

POST test/_search
{
  "runtime_mappings": {
    "host.ip_string": {
      "type": "keyword",
      "script": {
        "source": "emit(doc['host.ip'].value);"
      }
    }
  },
  "query": {
    "bool": {
      "must_not": [
        {
          "regexp": {
            "host.ip_string": "123\\.<16-31>\\.0\\..*"
          }
        }
      ]
    }
  }
}

相关问题