2. 关于默认分析使用term查询的问题

  之前说过es的默认分析器会讲中文拆分成一个个的单个汉子,搜索条件“内科”会被分析为“内”和“科”,从而进行搜索。而对于搜索我们常用的match搜索类似于数据库的模糊查询,term搜索为精确查询。使用的时候会出现以下情况:

2.1 场景

默认不对索引下的字段进行mapping操作时,使用的是默认分析器,假设有如下数据内容:

内科
内一科
内二科
普通内科
肿瘤内科

我们使用match搜索来搜索“肿瘤”,得到的结果显而易见是“肿瘤内科”,搜索“肿瘤内科”,得到的不仅是“肿瘤内科”,“内一科”等另外几个包含“内”、“科”的也会列出来,但是当我们使用term搜索“肿瘤”时,我们得到的是空的结果,这也是显而易见的,因为term是精确查询,“肿瘤”和“肿瘤内科”是不同的。那么如果我们term搜索“肿瘤内科”,理论上应该出现“肿瘤内科”才符合我们的预期。但是:

{"query":{"term":{"name":"肿瘤内科"}}
}
<-----------    result    ----------->
{"took": 1,"timed_out": false,"_shards": {"total": 5,"successful": 5,"skipped": 0,"failed": 0},"hits": {"total": 0,"max_score": null,"hits": []}
}

得到的结果依然是空的,我们更换搜索条件,输入“内科”,得到的依然是空的。但是当我们输入“肿”或者“肿瘤内科”的任意一个单字时,都可以的到“肿瘤内科”的结果,于此同时,“内”和“科”将会得到所有包含“内”和“科”字的数据。

2.2 分析原因

原因在上一节内容里已经提及,默认的分析器会讲中文分析称单个字,不会有任何联字,也就是说,4个字的“肿瘤内科”倒排索引是“肿“、”瘤“、”内“、”科”,使用term查询时,必须是以上四个单字中的某一个才行。那么这时候是不是和之前提到的搜索条件也需要进行对应的分析,根据分析的倒排索引就行查询相矛盾?这里我们需要先明白match查询和term查询的机制。

2.2.1 match查询的原理

  • 检查字段类型 。
    name 字段是一个 string 类型( analyzed )已分析的全文字段,这意味着查询字符串本身也应该被分析。这里的“肿瘤内科”会被分析为“肿“、”瘤“、”内“、”科”
  • 分析查询字符串 。
    将查询的字符串 “肿瘤内科” 传入标准分析器中,输出的结果是单个项 。因为只有一个单词项,所以 match 查询执行的是单个底层 term 查询。在这里也就是会将“肿“、”瘤“、”内“、”科”四个单字分别进行term查询
  • 查找匹配文档 。
    用 term 查询在倒排索引中查找 “肿“、”瘤“、”内“、”科” 然后获取一组包含该项的文档,本例的结果是文档:“内科”,“内一科”,“内二科”,“普通内科”,“肿瘤内科”,“内科”。
  • 为每个文档评分 。
    用 term 查询计算每个文档相关度评分 _score ,这是种将 词频(term frequency,即 “肿“、”瘤“、”内“、”科” 在相关文档的 name 字段中出现的频率)和反向文档频率(inverse document frequency,即词 “肿“、”瘤“、”内“、”科” 在所有文档的 name 字段中出现的频率),以及字段的长度(即字段越短相关度越高)相结合的计算方式。

2.2.2 term查询原理

首先需要注意的一点是,term查询是非评分查询,而match是评分查询,其次,term查询时,不会进行分词,而match查询前会跟去盖子段已经配置好的分析器进行相应的分析。其查询内部的操作为:

  • 查找匹配文档.
    term 查询在倒排索引中查找 “肿瘤内科” 然后获取包含该 term 的所有文档。本例中,显然没有符合的。

    切记index内的“肿瘤内科”并不是以直接的“肿瘤内科”存在,而是以“肿“、”瘤“、”内“、”科”四个单字存在

  • 创建 bitset.
    过滤器会创建一个 bitset (一个包含 0 和 1 的数组),它描述了哪个文档会包含该 term 。匹配文档的标志位是 1 。本例中,bitset 的值为 [0,0,0,0,0] 。在内部,它表示成一个 “roaring bitmap”,可以同时对稀疏或密集的集合进行高效编码。
  • 迭代 bitset(s)
    一旦为每个查询生成了 bitsets ,Elasticsearch 就会循环迭代 bitsets 从而找到满足所有过滤条件的匹配文档的集合。执行顺序是启发式的,但一般来说先迭代稀疏的 bitset (因为它可以排除掉大量的文档)。
  • 增量使用计数
    Elasticsearch 能够缓存非评分查询从而获取更快的访问,但是它也会不太聪明地缓存一些使用极少的东西。非评分计算因为倒排索引已经足够快了,所以我们只想缓存那些我们 知道 在将来会被再次使用的查询,以避免资源的浪费。
    所以这就解释了为什么使用term查询“肿瘤内科”,得不到“肿瘤内科”的额,而使用单子却能搜索到的问题了。

2.3 解决方式

通过对默认分析器的解读,其实无论是用默认的还是自行设置shingle等方式,对于汉子的term查询,没有一个标准的方式,使用shingle配置时,可以满足term搜索“肿瘤内科”得到“肿瘤内科”的结果,但是使用“瘤内科”,也会搜索到“肿瘤内科”,同样“内”也是,这取决于与在创建索引时的mapping中shingle最长度和最大长度的设置。所以,对于文本的搜索,term查询并非像mysql中的=一样。但是对于非文本类型,如bool和数字类型,或者大于小于等比较操作,使用term会非常的精准。

ElasticSearch term和match查询机制解析和隐藏的查询问题相关推荐

  1. java mysql 多表查询_解析Mysql多表查询的实现

    查询是数据库的核心,下面就为您介绍Mysql多表查询时如何实现的,如果您在Mysql多表查询方面遇到过问题,不妨一看. Mysql多表查询: CREATE TABLE IF NOT EXISTS co ...

  2. mysql教程多表查询_解析Mysql多表查询的实现

    查询是数据库的核心,下面就为您介绍Mysql多表查询时如何实现的,如果您在Mysql多表查询方面遇到过问题,不妨一看. Mysql多表查询: CREATE TABLE IF NOT EXISTS co ...

  3. elasticsearch7常见查询(term、match、bool、filter)

    一.精准查询term term是代表完全匹配,即不进行分词器分析,文档中必须包含整个搜索的词汇 1.term单值 字段只有一个值时候,用term关键词查询 查询biz_id值为190919002390 ...

  4. 【Elasticsearch教程18】Mapping字段类型之text 以及term、match和analyzer

    Elasticsearch Mapping字段类型之text 以及term.match和analyzer 一.text场景 二.`term`查询 三.`match`查询 1. `亚瑟王`如何存储? 2 ...

  5. Elasticsearch教程(28) text和keyword区别 term和match区别 ik中文分词器使用

    text和keyword区别 term和match区别 ik中文分词器使用 一.前言 二.之前相关的博客 三.造点测试数据 1. 创建一个index 2. 插入测试数据 四.做一份试卷 第1题:tit ...

  6. elasticsearch中term与match

    分词器.字符串类型.倒排索引 在说term和match之前,需要先了解一下这三个概念 分词器 es默认的分词器是standard analyzer,该分词器的特点是:将所有英文字符串的大写字母转换成小 ...

  7. elasticsearh中查询类型,term、match、match_all、multi_match、range、bool、boosting等

    查询方式有如下几种: GET /<index>/_search GET /_search POST /<index>/_search POST /_search 一般分为如下几 ...

  8. java操作es聚合操作并显示其他字段_java使用elasticsearch分组进行聚合查询过程解析...

    这篇文章主要介绍了java使用elasticsearch分组进行聚合查询过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 java连接elas ...

  9. ElasticSearch查询 第四篇:匹配查询(Match)

    <ElasticSearch查询>目录导航: ElasticSearch查询 第一篇:搜索API ElasticSearch查询 第二篇:文档更新 ElasticSearch查询 第三篇: ...

最新文章

  1. Cocos2d之Action类详解
  2. 基于SAAS模式的报销管理系统!
  3. 连贯的学习黑树(插入节点)
  4. 近视手术─医学界的一个阴谋? !
  5. c语言查看进程模块,计算机二级考试C语言辅导:进程模块查看
  6. python实现决策树数据直接赋值导入_Python3.0 实现决策树算法的流程
  7. dw如何制作图片自动切换效果_什么是3D虚拟展厅,虚拟展厅如何在线3D漫游!
  8. flex white-space: nowrap,撑大盒子问题
  9. Ubuntu Qt 编译问题
  10. 自动Shader优化器glsl_optimizer的编译与使用
  11. linux weblogic java_options_使用Linux脚本更新Weblogic部署的应用程序
  12. BootStrap-
  13. Studio启动的时候报错 Could not install Gradle distribution from
  14. 物理内存充足,但是为什么用代码总申请不到内存呢?
  15. double write buffer
  16. Linux 下文件IO编程进程控制实验
  17. 基于GD库的php验证码类(支持中英文字体、背景、干扰点线、扭曲…….)
  18. CMT 注册——Google Scholar Id,Semantic Scholar Id,和 DBLP Id
  19. 云服务器只能显示控制台吗,云服务器控制台使用方法
  20. DelphiXE7操作sqlite数据库

热门文章

  1. Gson、Fastjson和Jackson速度对比
  2. 了解某领域的研究进展与发展趋势
  3. Android 获取App可用内存
  4. Qt——多种风格的画笔画刷
  5. 《韭菜的自我修养》pdfmobiepub电子版
  6. 机器学习中的过拟合与解决办法
  7. HTTP代理和HTTPS代理的区别
  8. request包的使用和随机生成浏览器信息
  9. 产品经理,Facebook是如何面试产品实习生的
  10. Open3D安装及测试