提问人:Su Zirboni 提问时间:11/1/2023 更新时间:11/1/2023 访问量:25
Elastic/OpenSearch:查询复合 IP 范围,如 123。[16-31].0.*
Elastic/OpenSearch: query composite IP range like 123.[16-31].0.*
问:
我想运行一个查询来过滤掉 IP 范围,例如(包括 16 和 31)。一般示例:123.[16-31].0.*
GET _search
{
"query": {
"bool": {
"must": {
"match_phrase": {
"somefield": "somevalue"
}
},
"must_not": {
... ip filter ...
}
}
}
}
我该如何编写该部分?must_not
一个似乎有效的解决方案是将 16 个范围放在 :must_not
"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]
答:
0赞
imotov
11/1/2023
#1
生成 16 个范围是最快的解决方案。但是,如果您不运行此请求太多次,并且更愿意用一些 CPU 时间换取程序员的时间,则可以使用运行时映射将字段转换为字段。他们的方式,您将能够像对待任何其他文本字段一样对待此字段。因此,您可以执行以下操作: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\\..*"
}
}
]
}
}
}
评论
0赞
Su Zirboni
11/2/2023
感谢您@imotov的回答!对我有用的折衷方案是在硬编码查询中使用 16 个范围,并在手动测试时使用运行时映射转换......不能说我喜欢在一个文件中看到 16 个范围,但有效的就是有效的!
0赞
imotov
11/2/2023
那么,你介意@SuZirboni把这个问题标记为答案吗?
评论