DSL语法查询之text与正则匹配的遇到的问题记录
之前写过一遍文章《ES之DSL简单查询》:https://bbs.huaweicloud.com/blogs/423268。 实际使用中却遇到了一些问题,排查许久都未解决,留个记录。
背景介绍
前景:需要根据关键字进行排查,es中存储的字段中是否包含某些特殊字符, 但是这些特殊字符是一类, 例如地址中是否包含门牌号。 然后这个地址不是单纯就只是一个地址的字段,他可能是包含中一堆信息中的,综合考量使用regexp进行匹配是最好的,因为可以自定义各项规则,也可以匹配到一些关键词的位置。
文本举例:
// 需要注意,不是每个信息都是这样的,各种日志都有
/*
这是一段demo举例,不是真实的,xx.xx.xxclass{ anme=zhangsan,sex=1,......address=''}
*/
我需要的就是把所有address的信息查询出来
DSL举例:
// DSL语句大概逻辑:查询包含所有有address的数据,但是不需要查询address=北京的数据
{
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"regexp": {
"message": ".*address=.*" // 查询addresss
}
}
]
}
},
{
"bool": {
"must_not": [
{
"regexp": {
"message": ".*address=北京.*" // 排查address=北京的数据
}
}
]
}
},
{
"bool": {
"filter": [
{
"range": {
"@timestamp": {
"gte": "now-4800m",
"lte": "now"
}
}
}
]
}
}
]
}
},
"sort": [
{
"@timestamp": {
"order": "asc"
}
}
],
"_source": [
"@timestamp",
"message"
],
"size":100
}
原因分析
当然最后的查询是失败的,只要正则中加了=就会失败,思考的原因有:
1.语法错误 2.regexp中=为特殊字符 3.存储的信息=左右包含了特殊字符,导致不符合预期要求
1.语法错误 这个经过认真排查, 且未加=前,数据正常。 排除
2.dsl中regexp的语法,=为特殊字符 。 尝试使用 ".",转义等,依旧不行。 排除
3.拿到存储前的数据,左右无空格。 排除
结论
先咨询百度,但是这种问题,很难有结果,没有明确的错误原因,很难找到问题,大部分都是不搭边的结果。
最终确实没办法了, 于是尝试问了一下AI。 确实没想到,定位到问题了。 已经不是第一次感觉AI的强大了。唉,以后务必是AI或者使用AI的人天下。
原因:是因为查询中的message存储的类型为text字段类型,该类型的字段会对数据进行分词,分词规则暂时不知,但是大概率是把等号这些分掉了,text的分词目的主要是为了提高查询效率,增加索引。 如果直接使用正则进行查询,分词的结果是没办法进行匹配的,以为=已经被分掉了。不存在与索引中。
附AI的回答结果:在 Elasticsearch 中,text 类型的字段是用于全文搜索的,它会对文档中的文本进行分词,将其转换为一系列的词项。当使用 regexp 进行匹配时,Elasticsearch 会将 regexp 表达式编译成一个正则表达式,并对每个词项进行匹配。如果 regexp 表达式中包含等号,那么它将被视为一个特殊字符,用于表示字段值的结束。因此,当 Elasticsearch 对文本进行分词时,等号将被视为一个词项的结束,导致正则表达式无法正确匹配。为了解决这个问题,你可以使用双引号将 regexp 表达式括起来,这样等号就不会被视为特殊字符了。例如,使用"regexp:"pattern""而不是 regexp:pattern 。另外,你也可以使用其他的匹配方式,如 match_phrase 或 match_phrase_prefix,它们不会对文档进行分词,因此不会受到等号的影响。
解决方案
暂未解决,由于一些特殊原因,只有使用权,无更改权,如果有类似的问题,可以看看能不能用match这些解决, 不行的话,就考虑把信息存储keyword的,正则就能正常匹配到了
- 点赞
- 收藏
- 关注作者
评论(0)