Elasticsearch 查询革新:探索 Wildcard 类型的高效模糊匹配策略

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: Elasticsearch 查询革新:探索 Wildcard 类型的高效模糊匹配策略

1、背景

在生产使用中,Elasticsearch 除了精确匹配的要求,也会有模糊查询的场景。

2、解决方案探讨

面对这种问题 ,传统的解决方案有两种:

2.1 方案一:ngram 分词器

使用 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倍。

2.2 方案二:wildcard 查询

使用 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 字段类型来解决模糊匹配的场景需求。

3、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
      }
    }
  }
}

4、wildcard 原理

关于 wildcard 字段的实现,官方在推出该字段的时候发布了相关的说明:

新的 wildcard 字段使用以下两种数据结构以这种方式自动加速通配符和正则表达式搜索:

  • 字符串中所有3个字符序列的  n-gram 索引。
  • 完整原始文档值的 “二进制 doc value” 存储。第一点,底层还是 ngram 的分词去实现模糊查询的场景,但是这里的 ngram 颗粒度是 3,从功能上满足了模糊查询的需求和保证了 wildcard 查询的高性能。

第二点,使用了 ES 中常见的正排+列存数据存储格式 doc value,在这里一个主要的效果就是在自动查询验证由 n-gram 语法匹配产生匹配候选的同时利用了doc value格式相对较高的压缩比。

5、测试

现在来看下 wildcard 实际的表现。

5.1 空间大小

如下图所示,可以看到使用 wildcard 字段的索引与原索引相差不大。

5.2 查询效率

查询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左右,有明显效果。

6、小结

1.可以说 wildcard 字段类型满足了模糊查询的主要需求,同时也提供了相对较高的查询性能;

2.wildcard 针对于 ngram 分词器有着不小的空间优势。

3.wildcard 虽然有着不小的优势,但是查询效率与数据的区分度有着很强的关联,在一些区分度较低的场景下效率与性能消耗依旧很严重。

4.相比 ES 在精确查询场景优秀的性能表现(即 term keyword 的高效,平稳在毫秒级的返回),wildcard 字段在模糊查询场景下的使用还是需要研发人员根据实际场景测试选择。

7、作者介绍

金多安,Elastic 认证专家,Elastic资深运维工程师,死磕Elasticsearch知识星球嘉宾,星球Top活跃技术专家,搜索客社区日报责任编辑

铭毅天下审稿并做了部分微调。

推荐阅读


更短时间更快习得更多干货!

和全球 近2000+ Elastic 爱好者一起精进!

比同事抢先一步学习进阶干货!


相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
4天前
|
存储 固态存储 Java
Elasticsearch中查询性能优化
Elasticsearch中查询性能优化
199 0
|
3天前
|
SQL 关系型数据库 数据库
实时计算 Flink版产品使用合集之将数据写入Elasticsearch时,若Elasticsearch中的字段类型为date,对应的SQL类型应该是什么
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
23 0
|
4天前
|
存储 缓存 搜索推荐
深入理解Elasticsearch倒排索引原理与优化策略
总之,Elasticsearch的倒排索引是其高效全文搜索的核心。为了提高性能和可伸缩性,Elasticsearch采用了多种优化策略,包括压缩、分片、合并、位集合和近实时搜索等。这些策略使Elasticsearch成为处理大规模文本数据的强大工具。
13 0
|
4天前
|
搜索推荐 JavaScript Java
Elasticsearch 8.X 如何依据 Nested 嵌套类型的某个字段进行排序?
Elasticsearch 8.X 如何依据 Nested 嵌套类型的某个字段进行排序?
27 0
|
4天前
|
运维 测试技术 数据处理
Elasticsearch 优化查询中获取字段内容的方式,性能提升5倍!
Elasticsearch 优化查询中获取字段内容的方式,性能提升5倍!
18 0
|
4天前
|
存储 缓存 Java
Elasticsearch 8.X 聚合查询下的精度问题及其解决方案
Elasticsearch 8.X 聚合查询下的精度问题及其解决方案
17 0
|
4天前
|
SQL JSON DataWorks
DataWorks产品使用合集之DataWorks 数据集成任务中,将数据同步到 Elasticsearch(ES)中,并指定 NESTED 字段中的 properties 类型如何解决
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
25 0
|
4天前
|
自然语言处理 Java 索引
SpringBoot 实现 elasticsearch 查询操作(RestHighLevelClient 的案例实战)
SpringBoot 实现 elasticsearch 查询操作(RestHighLevelClient 的案例实战)
25 1
|
4天前
|
缓存 算法 索引
【Elasticsearch专栏 07】深入探索:Elasticsearch的倒排索引如何进行模糊查询和通配符查询
Elasticsearch的倒排索引支持模糊查询和通配符查询,通过特定的算法和数据结构,能够实现对关键词的模糊匹配和通配符匹配。这两种查询类型提供了更灵活的搜索功能,但可能影响查询性能,需结合优化策略使用。
148 0
|
4天前
|
API 索引
Elasticsearch Index Shard Allocation 索引分片分配策略
Elasticsearch Index Shard Allocation 索引分片分配策略
79 1

热门文章

最新文章