DSL语法查询之text与正则匹配的遇到的问题记录

举报
object 发表于 2024/06/14 17:13:45 2024/06/14
【摘要】 之前写过一遍文章《ES之DSL简单查询》:https://bbs.huaweicloud.com/blogs/423268。 实际使用中却遇到了一些问题,排查许久都未解决,留个记录。背景介绍前景:需要根据关键字进行排查,es中存储的字段中是否包含某些特殊字符, 但是这些特殊字符是一类, 例如地址中是否包含门牌号。 然后这个地址不是单纯就只是一个地址的字段,他可能是包含中一堆信息中的,综合考量...

之前写过一遍文章《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的,正则就能正常匹配到了

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。