如何在OpenSearch的@message/msg字段中筛选dSId为空的记录
筛选msg或@message字段中dSId为空的记录解决方案
问题根源
你的msg和@message字段都是字符串类型,并非结构化的嵌套JSON对象,所以直接通过_source.msg.dSId这种字段路径查询完全无效——dSId只是字符串里的一段文本,不是独立的嵌套字段。之前的exists过滤器出错,就是因为你试图查询一个不存在的嵌套字段,导致逻辑完全反向。
可行查询方法
根据你的需求,推荐两种高效的字符串匹配方案:
方案1:使用match_phrase精准匹配
利用短语匹配,直接查找包含dSId: (冒号后带空格,对应示例中空值的格式)的记录:
{ "query": { "bool": { "should": [ { "match_phrase": { "_source.msg": "dSId: " } }, { "match_phrase": { "_source.@message": "dSId: " } } ], "minimum_should_match": 1 } } }
should数组表示满足任意一个条件即可minimum_should_match:1确保至少匹配msg或@message中的一个
方案2:使用regexp正则匹配
如果空值的格式有细微变化(比如冒号后有多个空格或直接跟逗号),可以用正则匹配更灵活的场景:
{ "query": { "bool": { "should": [ { "regexp": { "_source.msg": "dSId:\\s*," } }, { "regexp": { "_source.@message": "dSId:\\s*," } } ], "minimum_should_match": 1 } } }
\\s*匹配0个或多个空白字符- 正则匹配
dSId:后直接跟逗号的场景,精准对应空值情况
备选方案:解析@message的JSON字符串(性能稍差)
如果@message是标准JSON字符串,也可以通过脚本解析后判断,但需要Elasticsearch开启脚本支持,且性能不如前两种方案:
{ "query": { "bool": { "should": [ { "match_phrase": { "_source.msg": "dSId: " } }, { "script": { "script": { "source": "def parsedMsg = JSON.parse(ctx._source['@message']); return parsedMsg.msg != null && parsedMsg.msg.contains('dSId: ');" } } } ], "minimum_should_match": 1 } } }
为什么之前的方法无效
exists过滤器:你查询的_source.msg.dSId是不存在的嵌套字段(msg是字符串而非对象),exists: true会返回所有不包含该字段的记录,和需求完全反向。- 之前的正则查询:直接用
dSId作为字段名,但dSId不是独立字段,所以查询根本无法定位目标内容。
内容的提问来源于stack exchange,提问作者Srinath Menon
相关产品推荐
相关产品推荐

