Elasticsearch学习--查询(prefix、wildcard、regexp、fuzzy)

本文探讨了搜索引擎中前缀搜索、通配符匹配和模糊查询的原理、优缺点,包括fuzzy查询的编辑距离、match_phrase_prefix与N-gram技术的应用。重点讲解了如何利用这些技术优化搜索性能和空间占用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、前缀搜索 prefix

  • 不计算相关度评分
  • 性能较差
  • 前缀搜索匹配的是分词后的词项
  • 前缀搜索没有缓存
  • 前缀搜索尽可能把前缀长度设置的更长
GET product/_search
{
  "query": {
    "fuzzy": {
      "name": {
        "value": "product1"
      }
    }
  }
}

index_prefixes为词项创建倒排索引,

比如computer这个单词,本身是一个词项,index_prefixes可以为这个单词再创建倒排索引,min_chars=2,max_chars=5的话,创建的索引:co、com、comp、compu

PUT prefixindex
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "analyzer": "ik_max_word",
        "index_prefixes": {
          "min_chars": 2,
          "max_chars": 3
        }
      }
    }
  }
}

优缺点:

优点:加快前缀索引的搜索效率

缺点:占用内存、空间

二、通配符 wildcard

匹配的也是分词后的词项term

# 造数据
PUT testindex/_doc/1
{
  "name":"zhang san"
}

PUT testindex/_doc/2
{
  "name":"zhang si"
}

PUT testindex/_doc/3
{
  "name":"zhuang san"
}


PUT testindex/_doc/4
{
  "name":"zhuang si"
}
# 用法
GET testindex/_search
{
  "query": {
    "wildcard": {
      "name": {
        "value": "*san"
      }
    }
  }
}

* 数组中的每个值都是精准值

 三、正则 regexp

1. 用法

GET testindex/_search
{
  "query": {
    "regexp": {
      "name": ".*san"
    }
  }
}

2. flags参数含义

 四、模糊查询 fuzzy

1. 情况

1)混淆字符(box->fox)

2) 缺少字符(black->lack)

3) 多出字符(sic -> sick

4) 颠倒次序(act-> cat)

2. 用法

GET testindex/_search
{
  "query": {
    "fuzzy": {
      "name": "xiaolahu"
    }
  }
}

 3. 参数

编辑距离:把字符改成正确的,需要挪到的次数

GET testindex/_search
{
  "query": {
    "fuzzy": {
      "name": {
        "value": "xiaoloahu",
        "fuzziness": 1,
        "transpositions":false
      }
    }
  }
}

 fuzziness, 默认是auto,根据字符串长度,从0,1,2取值

 4. match查询也支持fuzziness

GET testindex/_search
{
  "query": {
    "match": {
      "name": {
        "query":"xiaoloahu",
        "fuzziness": 1
      }
    }
  }
}

 match是分词的,fuzzy是不分词的

fuzzy不适合数据量大时使用

五、match_phrase_prefix

match_phrase

match_phrase会分词

被检索字段必须包含match_phrase中的所有词项并且顺序必须是相同的

被检索字段包含的match_phrase中的词项之间不能有其他词项

match_phrase_prefix概念

match_phrase_prefix与match_phrase相似,但是它多了一个特性,就是它允许在文本的最后一个词项(term)上的前缀匹配

如果是一个单词,比如a,它会匹配文档字段所有以a开头的文档

如果是一个短语,比如 "this is ma" ,他会先在倒排索引中做以ma做前缀搜索,然后在匹配到的doc中做match_phrase查询

参数

max_expansions:限制匹配的最大词项,默认50;越大越消耗性能,可以通过减少这个值,提高性能

analyzer:指定何种分析器来对该短语进行分词处理

boost :用于设置该查询的权重

slop :允许短语间的词项(term)间隔

slop 参数告诉 match_phrase 查询词条相隔多远时仍然能将文档视为匹配

什么是相隔多远? 意思是说为了让查询和文档匹配你需要移动词条多少次

六、N-gram和edge ngram

ngram可以用于切词器(比分词器粒度更小)

GET _analyze
{
  "tokenizer": "ngram",
  "text": "reba always loves me"
}

有两个主要参数

min_gram:创建索引所拆分字符的最小阈值

max_gram:创建索引所拆分字符的最大阈值

ngram也可以用于词项过滤器token filter

GET _analyze
{
  "tokenizer": "ik_max_word",
  "filter": [ "ngram" ],
  "text": "reba always loves me"
}

优点:做模糊搜索时,粒度更细

缺点:占用大量的磁盘空间

Edge n-gream

ngram适用于前缀、中缀、后缀搜索

Edge n-gream只适用于前缀搜索,但也会更节省空间

Edge n-gream的性能比match_phrase_prefix更高

### Elasticsearch 中不同类型查询及其用法 #### 精确匹配查询类型 ##### Term 查询 `Term` 查询用于精确查找文档中的特定术语。此操作不经过分析器处理,因此非常适合用于结构化数据字段。 ```json GET /_search { "query": { "term": { "user.id": "kimchy" } } } ``` 该命令会返回 `user.id` 字段等于 `"kimchy"` 的所有记录[^4]。 ##### Terms 查询 当需要在一个集合内寻找多个可能的值时可以使用 `Terms` 查询: ```json GET /_search { "query": { "terms": { "tag": ["blue", "green"] } } } ``` 上述例子将检索标签为蓝色或绿色的所有项目[^2]。 ##### Exists Must_Not 存在性查询 为了验证某个字段是否存在,可采用 `Exists` 或者其否定形式 `Must_Not` 来实现过滤功能。 存在性的判断可以通过下面的方式完成: ```json GET /_search { "query": { "bool": { "must_not": { "exists": { "field": "email" } } } } } ``` 这段代码表示只获取那些没有电子邮件地址的用户资料。 ##### Range 范围查询 对于数值型或者日期时间戳的数据来说,范围查询非常有用;它允许设定上下限来限定结果集。 例如要找到价格介于10到20之间的商品: ```json GET /_search { "query": { "range": { "price": { "gte": 10, "lte": 20 } } } } ``` 这里定义了一个闭区间 `[10, 20]` ,即大于等于10且小于等于20的商品都会被选中。 ##### Prefix 前缀查询 如果希望基于字符串开头部分来进行搜索,则应该考虑使用 `Prefix` 查询方式。 比如想要得到所有以字母 'k' 开头的名字列表: ```json GET /_search { "query": { "prefix" : { "name.first" : "k" } } } ``` 这将会选出名字首字符是 'k' 的所有人名[^3]。 ##### Ids 查询 针对已知 ID 集合的情况,可以直接利用 `Ids` 查询快速定位目标对象而无需遍历整个索引库。 假设我们有三个产品的ID分别是 `1`, `4`, `100` : ```json GET /_search { "query": { "ids": { "values": ["1", "4", "100"] } } } ``` 这样就可以一次性取得这三个产品详情页的信息了。 ##### Wildcard 通配符查询 类似于 SQL 中使用的 `%` 符号,在 ES 中也有类似的通配符支持,可用于更灵活的文字模式匹配。 例如,如果我们想知道姓氏是以 'smi*' 结尾的人有哪些: ```json GET /_search { "query": { "wildcard": { "last_name": "smi*" } } } ``` 这里的星号代表任意数量(包括零个)其他字符。 ##### Regexp 正则表达式查询 正则表达式的强大之处在于能够创建复杂的文本匹配规则,适用于更加精细控制的需求场景下。 如需查找出电话号码格式符合某种规律的所有联系人信息: ```json GET /_search { "query": { "regexp": { "phone_number": "[789][0-9]{9}" } } } ``` 此处给出的是印度手机号码的一种常见格式:首位数字必须是7、8或9,后面跟随九位数任何整数。 ##### Fuzzy 模糊查询 最后介绍一种特别适合拼写错误容忍度较高的场合下的工具——模糊查询(`Fuzzy`) 。 它通过设置最大编辑距离参数来自动生成近似词条并尝试匹配实际存在的词汇表项。 举个简单的例子,即使输入关键词略有偏差也能成功命中预期的结果: ```json GET /_search { "query": { "fuzzy" : { "user" : "ki" } } } ``` 在此基础上还可以进一步调整诸如 `max_expansions` 参数等细节配置项以优化性能表现[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值