在生产使用中,Elasticsearch 除了精确匹配的要求,也会有模糊查询的场景。
我们提供的服务有:成都网站建设、网站建设、微信公众号开发、网站优化、网站认证、怀远ssl等。为数千家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的怀远网站制作公司
面对这种问题 ,传统的解决方案有两种:
使用 ngram 分词器对存入的数据进行精细化的拆分,利用细颗粒度的 token 进行快速的召回。
这是一个利用空间换时间的方案,细化查询所需的词根内容,利用精确匹配结果大范围的命中来达到模糊效果。
PUT test-005
{
"settings": {
"index.max_ngram_diff": 10,
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "my_tokenizer"
}
},
"tokenizer": {
"my_tokenizer": {
"type": "ngram",
"min_gram": 3,
"max_gram": 10,
"token_chars": [
"letter",
"digit"
]
}
}
}
},
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "my_analyzer",
"fields": {
"keyword": {
"type": "keyword"
}
}
}
}
}
}
POST test-005/_bulk
{"index":{"_id":1}}
{"title":"英文官网承认刘强东一度被捕的原因是涉嫌性侵"}
{"index":{"_id":2}}
{"title":"别提了朋友哥哥刘强东窗事发了"}
{"index":{"_id":3}}
{"title":"刘强东施效颦,没想到竟然收获了流量"}
{"index":{"_id":4}}
{"title":"刘强东是谁?我不认识"}
POST test-005/_search
{
"query": {
"match_phrase": {
"title": "刘强东"
}
}
}
这里有个明显的使用案例,如下图所示,使用 ngram 的 test2 索引比原来使用 keyword 的索引空间大小大了接近10倍。
图片
使用 wildcard 查询,这是一项支持通配符的模糊检索功能,有点类似 SQL 中的 like 匹配。
为了实现通配符和正则表达式的查询,Ealsticsearch 依赖的 Lucene4.0 会将输入的字符串模式构建成一个DFA (Deterministic Finite Automaton),而带有通配符的pattern构造出来的DFA可能会很复杂,开销很大。
具体分析:
https://elasticsearch.cn/article/171
https://elasticsearch.cn/article/186
面对两个各有所长,甚至有点“卧龙凤雏”的方案,ES 在 7.9 版本推出了 wildcard 字段类型来解决模糊匹配的场景需求。
Elasticsearch 的 wildcard 字段类型最早在 7.9 版本中引入。这个版本加入了对 wildcard 类型的支持,旨在改善模糊匹配的查询效率和性能,特别是在处理大量文本数据时。这一新特性主要针对了之前版本中 wildcard 查询的性能问题,提供了更高效的方式来处理通配符和正则表达式的搜索需求。
图片
https://www.elastic.co/guide/en/elasticsearch/reference/7.9/release-highlights.html
我们先来看下 wildcard 类型怎么使用:
先定义一个 wildcard 类型的字段
PUT my-index-000001
{
"mappings": {
"properties": {
"my_wildcard": {
"type": "wildcard"
}
}
}
}
为其写入一个文档
PUT my-index-000001/_doc/1
{
"my_wildcard" : "This string can be quite lengthy"
}
然后使用 wildcard 查询如下所示:
GET my-index-000001/_search
{
"query": {
"wildcard": {
"my_wildcard": "*quite*lengthy"
}
}
}
结果为
{
"took" : 6,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 3.8610575,
"hits" : [
{
"_index" : "my-index-000001",
"_type" : "_doc",
"_id" : "1",
"_score" : 3.8610575,
"_source" : {
"my_wildcard" : "This string can be quite lengthy"
}
}
]
}
}
有时候我们需要忽略大小写,可以在 wildcard 查询使用 case_insensitive 参数。
GET my-index-000001/_search
{
"query": {
"wildcard": {
"my_wildcard": {
"value": "*Quite*lengthy",
"case_insensitive": true
}
}
}
}
关于 wildcard 字段的实现,官方在推出该字段的时候发布了相关的说明:
新的 wildcard 字段使用以下两种数据结构以这种方式自动加速通配符和正则表达式搜索:
第二点,使用了 ES 中常见的正排+列存数据存储格式 doc value,在这里一个主要的效果就是在自动查询验证由 n-gram 语法匹配产生匹配候选的同时利用了doc value格式相对较高的压缩比。
现在来看下 wildcard 实际的表现。
如下图所示,可以看到使用 wildcard 字段的索引与原索引相差不大。
图片
查询dsl |
keyword类型 |
wildcard类型 |
wildcard:”红豆” |
715ms |
71ms |
wildcard:”006-612014” |
633ms |
22ms |
wildcard:”55” |
584ms |
188ms |
wildcard:”11” |
1359ms |
357ms |
注:这里省却了索引详细信息,只需知道是同一个索引的比对测试。
综上所述,在模糊搜索字段区分度很低的情况下 如:模糊查询单个数字,此时优化效率rt大概是之前的1/3左右,区分度高的场景rt大概是之前的1/15左右,有明显效果。
1.可以说 wildcard 字段类型满足了模糊查询的主要需求,同时也提供了相对较高的查询性能;
2.wildcard 针对于 ngram 分词器有着不小的空间优势。
3.wildcard 虽然有着不小的优势,但是查询效率与数据的区分度有着很强的关联,在一些区分度较低的场景下效率与性能消耗依旧很严重。
4.相比 ES 在精确查询场景优秀的性能表现(即 term keyword 的高效,平稳在毫秒级的返回),wildcard 字段在模糊查询场景下的使用还是需要研发人员根据实际场景测试选择。
金多安,Elastic 认证专家,Elastic资深运维工程师,死磕Elasticsearch知识星球嘉宾,星球Top活跃技术专家,搜索客社区日报责任编辑
铭毅天下审稿并做了部分微调。
标题名称:Elasticsearch查询革新:探索Wildcard类型的高效模糊匹配策略
网址分享:http://www.csdahua.cn/qtweb/news4/281554.html
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网