OpenSearch正则查询DSL中冒号无法正常使用的问题排查
问题分析与解决办法
为什么你的查询失效?
- 正则加
:/.查不到:你的message字段应该是text类型,Elasticsearch会对text字段做分词处理,把{"id":"abc123","duration":120}拆成id、abc123、duration、120这类单独的词,不存在"duration":这样的完整分词项,所以正则匹配不到。 range查询message.duration无效:因为message是字符串类型,不是嵌套对象,Elasticsearch没法自动解析字符串里的JSON结构,所以message.duration这个字段根本不存在。
两种解决方案
方案一:修改字段映射(最优解)
把message的类型改成object,让Elasticsearch自动解析JSON内容为结构化字段。
- 如果是新建索引,设置映射:
{ "mappings": { "properties": { "message": { "type": "object" } } } }
- 如果是已存在的索引,需要重新索引数据到新的、带有上述映射的索引中。
之后就能用你的range查询正常筛选了:
{ "query": { "range": { "message.duration": { "gt": 200 } } } }
方案二:用正则匹配(无需修改映射)
利用message.keyword字段(不分词,保存完整字符串),写正则匹配duration值大于200的情况:
{ "query": { "regexp": { "message.keyword": "\"duration\":\\s*([2-9]\\d{2}|\\d{4,})" } } }
正则说明:
\"duration\":匹配JSON里的"duration":\\s*匹配冒号后可能存在的空格([2-9]\\d{2}|\\d{4,})匹配大于等于200的数字:200-999用[2-9]\d{2},1000及以上用\d{4,}
内容的提问来源于stack exchange,提问作者NothingBox
相关产品推荐
相关产品推荐

