检索类型脑图:
微信图片_20220531093636.png

精准匹配检索和全文检索的本质区别

精准匹配检索和全文检索的本质区别:

  • 精准匹配把检索的整个文本不做分词处理,当前一个串整体处理。
  • 而全文检索需要分词处理,对分词后的每个词单独检索然后大bool组合检索。

直接用列子来看:

//mapping映射
PUT test
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "ik_max_word",
        "fields": {
          "keyword": {
            "type": "keyword"
          }
        }
      }
    }
  }
}
//利用bulk批量插入数据
POST test/_bulk
{"index":{"_id":1}}
{"title":"乌兰图雅经典歌曲30首连播 标清_手机乐视视频"}
{"index":{"_id":2}}
{"title":"乌兰县地区生产总值22.9亿元 "}
{"index":{"_id":3}}
{"title":"乌兰新闻网欢迎您!"}
{"index":{"_id":4}}
{"title":"乌兰:你说急什么呢,我30岁了"}
{"index":{"_id":5}}
{"title":"千城胜景丨胜境美誉 多彩乌兰"}

利用以下搜索来说明:

POST test/_search
{
  "profile": true, 
  "query": {
    "match": {
      "title": "乌兰新闻网欢迎您!"
    }
  }
}

结果为:
2022-05-31T01:44:38.png
为什么通过检索“乌兰新闻网欢迎您!”召回了全部数据???

我们加上"profile": true看下:
2022-05-31T01:47:09.png

简单来说一句话:match_query 在检索的时候将待检索字符串做了分词处理。

我们可以通过analyzer API 看出:
2022-05-31T01:49:16.png

精准匹配的检索实现:

POST test/_search
{
  "profile": true, 
  "query": {
    "term": {
      "title.keyword": "乌兰新闻网欢迎您!"
    }
  }
}

结果:
2022-05-31T01:50:52.png
也就是说,精准匹配是拿整个文本串一起 term query检索的,不做分词处理。

精准匹配检索

  1. Term单字段精准匹配
  • Term query 应用场景:单值精准匹配。
  • 注意点:避免将 term query 应用到 text 类型的检索。

再延伸一些,Term 检索针对的是非 text 类型,term 针对 text 类型并不会报错,但结果会达不到预期。
如果我非要将 text 类型应用 term query会怎么样?来吧,看一下效果:

DELETE my-index-000001
# 不指定分词器就使用默认:standard 分词器。
PUT my-index-000001
{
  "mappings": {
    "properties": {
      "full_text": {
        "type": "text"
      }
    }
  }
}
# 写入数据
PUT my-index-000001/_doc/1
{
  "full_text": "Quick Brown Foxes!"
}

# 执行检索,并不会召回数据
GET my-index-000001/_search?pretty
{
  "profile": true, 
  "query": {
    "term": {
      "full_text": "Quick Brown Foxes!"
    }
  }
}

2022-05-31T02:12:09.png
检索结果如上图所示,为啥没有召回结果数据?

原因在于:写入的时候,Quick Brown Foxes! 经过默认分词器 standard 处理后,转化为:quick、brown、foxes 存储。
2022-05-31T02:13:43.png

  1. Terms 多字段精准匹配
  • Terms query 应用场景:多值精准匹配。

注意点:同 term query核心区别:terms query 支持多个值,而 term query 仅支持单个值。

  1. Range 范围检索
  • Range query 应用场景:区间范围检索。

注意点1:当“search.allow_expensive_queries”设置为 false 时,range query 在 text 和 keyword 类型的检索不能被执行。
注意点2:range query 对 text、keyword 类型的区间检索实际意义不大。

  1. Exists 是否存在检索
  • Exists query 应用场景:判定字段是否有值。
  1. Wildcard 类Mysql like 检索
  • Wildcard 应用场景:通配符检索,类似 MySQL like 查询。
    2022-05-31T02:21:39.png

    1. prefix 前缀匹配检索
  • prefix Query应用场景:前缀匹配。

    1. Terms set 检索

Terms set Query 应用场景:term query 检索 1个满足条件,terms query检索多个满足条件,而 Terms set query 介于两者中间。

  1. Fuzzy 支持编辑距离的模糊查询

Fuzzy Query 应用场景:返回包含与搜索词相似的词的文档,也就是说:有一定的类似纠错功能。

  1. IDs 检索

IDS query:基于 ID 组召回数据。

  1. Regexp 正则匹配检索

Regexp Query:基于正则表达式的检索。
使用建议:非必要不使用。

全文检索类型

  1. Match 检索
  • Match Query 应用场景:召回率要求高、精准度要求不高的场景。
  • 使用建议:精准度要求高的场景慎用。

如前所述,Match 的本质:大 bool + term query 组合体。
2022-05-31T02:31:43.png

  1. Match phrase 短语检索
  2. Match phrase Query 应用场景:更注重精准度召回的场景,match query 如果叫做分词检索的话,match phrase 叫短语匹配检索更为合适。

注意1:检索的时候可以指定分词器。
注意2:分词器指定不同,拼接的串中字符的切分粒度不同。
如下两个截图分别使用了:standard 标准分词器以及 ik_smart 粗粒度 IK 分词器。
2022-05-31T02:34:41.png
2022-05-31T02:34:57.png

  1. Multi-match 检索
  2. Multi-match query 应用场景:多字段的 match query。

注意:多字段就涉及评分的整合,所以会有:most_fields、best_fields、cross_fields 等评分方式。

  1. Match_phrase_prefix 检索
  2. Match_phrase_prefix query 应用场景:短语匹配+前缀匹配的组合体,适用于短语前缀匹配。

2022-05-31T02:36:33.png

  1. query_string 检索
  2. query_string query 应用场景:与或非表达式的检索。

AND:代表与,OR 代表或,NOT 代表非。
非常复杂的语法,建议参考官方文档。

  1. simple_query_string 检索

simple_query_string 应用场景:同 query_string 。
核心不同点:simple_query_string 在语法不对时,并不会报错。

组合检索类型

组合检索主要分为两大类:bool 组合检索和自定义评分检索。

  1. bool 组合检索

适用场景:复杂条件的组合检索。当单个或者单类检索条件不能适配复杂组合检索的时候,优先考虑 bool 组合条件检索。
其下可以包含但不限于:
must:必须满足条件。
must_not:必须不满足条件(忽略评分,召回数据评分为0)。
filter:过滤条件(忽略评分,召回数据评分为0),可以借助缓存提升性能。
should:部分条件满足,由minmum_should_match控制。

  1. 自定义评分检索

适用场景:传统基于BM25(词频TF、逆文档频率IDF)机制不能满足评分要求,某一个或者多个字段需要提升、降低或者修改权重比例的时候,优先考虑自定义评分实现。
如果自定义评分也无法满足,那只能自己开发评分插件实现。
自定义评分推荐阅读:实战 | Elasticsearch自定义评分的N种方法

总结

2022-05-31T02:43:52.png
全文检索(Full text query)类检索

  • Match 适用于:召回率高、精准度不高的场景;
  • Match phrase 适用于:精准度高、召回率不高的场景;
  • Match phrase prefix 适用于:短语前缀匹配检索;
  • Mulit-match 适用于:多字段检索;
  • Query string 适用于:支持与或非表达式的检索;
  • Simple query string:较 query string 容错率高的场景;

精准匹配(Term-level query)类检索

  • Term 适用于:单字段精准匹配;
  • Terms 适用于:多字段精准匹配;
  • Range 适用于:范围检索;
  • Exists 适用于:判定是否存在检索;
  • Wildcard 适用于:类Mysql like 检索,非必要不使用;
  • prefix 适用于:前缀匹配检索;
  • Fuzzy 适用于:支持编辑距离的模糊查询;
  • IDs 适用于:基于文档id组检索的场景;
  • Regexp 适用于:正则匹配检索,非必要不使用。

2022-05-31T02:44:17.png

文章来源:干货 | Elasticsearch 检索类型选型指南

最后修改:2022 年 05 月 31 日
如果觉得我的文章对你有用,请随意赞赏