本节书摘来自华章出版社《深入理解Elasticsearch(原书第2版)》一书中的第2章,第2.2节,作者[美]拉斐尔·酷奇(Rafal Ku) 马雷克·罗戈任斯基(Marek Rogoziski),更多章节内容可以访问云栖社区“华章计算机”公众号查看

2.2 查询改写

之前我们探讨了评分机制,这些知识非常珍贵,特别是当你尝试改进查询相关性时。我们还认为,在对查询进行调试时,也很有必要搞清楚查询是如何执行的。因此我们决定在本节介绍一下查询改写是如何工作的,为什么需要查询改写,以及我们应该如何控制它。
如果你之前使用过诸如前缀查询或通配符查询之类的查询类型,那么你会了解这些都是基于多词项的查询,它们都涉及查询改写。Elasticsearch使用查询改写是出于对性能的考虑。从Lucene的角度来看,所谓的查询改写操作,就是把费时的原始查询类型实例改写成一组性能更高的查询类型实例,从而加快查询执行速度。查询改写过程对客户端不可见,不过最好能够知道我们可以修改查询改写过程。举个例子,让我们看看Elasticsearch是如何处理前缀查询的。
2.2.1 前缀查询示例
演示查询改写过程的最好方式莫过于通过范例深入了解该过程的内部实现机制,尤其是要去了解原始查询中的词项是如何被改写成目标查询中那些词项的。假设我们索引了下面这些文档中的数据:



现在我们想找出索引中所有name字段以字母j开头的文档。简单起见,我们在clients索引中执行以下查询:


这里使用了一个简单的前缀查询,想检索出所有name字段以字母j开头的文档。我们同时也设置了查询改写属性以确定执行查询改写的具体方法,不过现在我们跳过该参数,具体的参数值将在本章的后续部分讨论。
执行前面的查询以后,我们将得到下面的结果:



如你所见,返回结果中有3个文档,这些文档的name字段以字母j开头。我们并没有显式设置待查询索引的映射,因此Elasticsearch探测出了name字段的映射,并将其设置为字符串类型并进行文本分析。可使用下面的命令进行检查:


Elasticsearch将返回类似下面的结果:


2.2.2 回到Apache Lucene
现在我们回到Lucene。如果你还记得Lucene倒排索引是如何构建的,你会指出倒排索引中包含了词项、词频以及文档指针(如果忘了,请重新阅读1.1节)。现在我们看看之前存储到clients索引中的数据大概是如何组织的。


Term这一列非常重要。如果我们去探究Elasticsearch和Lucene的内部实现,将会发现前缀查询被改写为下面这种查询:


我们可以用Elasticsearch API来检查重写片段。首先,使用Explain API执行如下命令:


执行结果如下:


可以看到,Elasticsearch对name字段使用了一个词项是joe的constant_score查询。当然,这一步发生在Lucene中,Elasticsearch实际上只是从缓存中获取这些词项。这一点可以用Validate查询API来验证。



Elasticsearch返回的结果如下:


2.2.3 查询改写的属性
当然,多词项查询的rewrite属性也可以支持除了“constant_score_boolean”之外的其他取值。我们可以通过这个属性来控制查询在Lucene内部的改写方式。我们可以将rewrite参数存放在代表实际查询的JSON对象中,例如,像下面的代码这样:


现在让我们来看看rewrite参数有哪些选项可以配置。
scoring_boolean:该选项将每个生成的词项转化为布尔查询中的一个或从句(Boolean should clause)。这种改写方法需要针对每个文档都计算得分。因此,这种方法比较耗费CPU(因为要计算和保存每个词项的得分),而且有些查询生成了太多的词项,以至于超出了布尔查询默认的1024个从句的限制。默认的布尔查询限制可以通过设置Elasticsearch.yml文件的index.query.bool.max_clause_count属性来修改。用户需谨记,改写后的布尔查询的从句数越多,查询性能越低。
constant_score_boolean:该选项与前面提到过的scoring_boolean类似,但是CPU耗费更少,这是因为并不计算每个从句的得分,而是每个从句得到一个与查询权重相同的一个常数得分,默认情况下等于1,我们也可以通过设置查询权重来改变这个默认值。与scoring_boolean类似,该选项也有布尔从句数的限制。
constant_score_filter:正如Lucene的Javadocs描述的那样,该选项按如下方式改写原始查询—通过顺序遍历每个词项来创建一个私有的过滤器,标记所有包含这个词项的文档。命中的文档被赋予一个与查询权重相同的常量得分。当命中词项数或文档数较大时,该方法比scoring_boolean 和constant_score_boolean执行速度更快。
top_terms_N:该选项将每个生成的词项转化为布尔查询中的一个或从句,并保存计算出来的查询得分。与scoring_boolean不同之处在于,该方法只保留最佳的N个词项,以避免触及布尔从句数的限制,并提升查询整体性能。
top_terms_boost_N:该选项与top_terms_N类似,不同之处在于它的文档得分不是通过计算得出的,而是被设置为跟查询权重(boost)一致,默认值为1。
 当rewrite属性设置为constant_score_auto或者没有设置时,Elasticsearch会根据查询的类型及其构造方式来决定是使用constant_score_filter还是constant_score_boolean。
现在,让我们再看一个例子。如果我们想在范例查询中使用top_terms_N选项,并且N的值设置为2,那么查询看起来与下面的代码类似:


从Elasticsearch返回的结果中可以看出,和我们之前使用的查询不同,这里的文档得分都不等于1.0。



这是因为top_terms_N需要保留得分最高的N个词项。
结束本节之前,读者应该会产生一个疑问,我们如何决定何时采用何种查询改写方法?该问题的答案更多地取决于您的应用场景。简单来说,如果您能接受较低的精度和相关性(但是追求更高的性能),那么可以采用top-N查询改写方法。如果您需要更高的查询精度和更好的相关性(同时可以接受较低的性能),那么应该采用布尔方法。

《深入理解Elasticsearch(原书第2版)》一2.2 查询改写相关推荐

  1. 深入理解ElasticSearch(原书第2版)

    为了方便人们从海量信息中快速检索出内容,搜索引擎应运运出.ElasticSearch是一个款基于apache lucene 的开源搜索引擎,它具有开源,分布式,准实时,restful,便于二次开发等特 ...

  2. 虚拟内存(深入理解计算机系统原书第3版9节读书笔记)

    深入理解计算机系统(原书第3版)读书笔记,其实就是嚼碎了原文然后把一部分挑了出来摘要,免得读着读着忘了 文章目录 前言 一.物理和虚拟寻址 二.地址空间 三.虚拟内存作为缓存的工具 1.DRAM缓存的 ...

  3. Linux设备驱动程序(第三版)/深入理解计算机系统(原书第2版)/[Android系统原理及开发要点详解].(韩超,梁泉)百度云盘下载

    文档下载云盘连接:http://pan.baidu.com/s/1dDD2sgT 更多其他资料,请关注淘宝:http://shop115376623.taobao.com/ http://item.t ...

  4. 《深入理解Elasticsearch(原书第2版)》——第2章 查询DSL进阶 2.1 Apache Lucene默认评分公式解释...

    本节书摘来自华章计算机<深入理解Elasticsearch(原书第2版)>一书中的第2章,第2.1节,作者 [美]拉斐尔·酷奇(Rafal Ku)马雷克·罗戈任斯基(Marek Rogoz ...

  5. 《深入理解Elasticsearch(原书第2版)》——1.4 小结

    本节书摘来自华章计算机<深入理解Elasticsearch(原书第2版)>一书中的第1章,第1.4节,作者 [美]拉斐尔·酷奇(Rafal Ku)马雷克·罗戈任斯基(Marek Rogoz ...

  6. 《深入理解Elasticsearch(原书第2版)》一1.3 在线书店示例

    本节书摘来自华章出版社<深入理解Elasticsearch(原书第2版)>一书中的第1章,第1.3节,作者[美]拉斐尔·酷奇(Rafal Ku) 马雷克·罗戈任斯基(Marek Rogoz ...

  7. 深入理解Elasticsearch(原书第2版)》一1.2 何为Elasticsearch

    本节书摘来华章计算机<深入理解Elasticsearch(原书第2版)>一书中的第1章 ,第1.2节,[美]拉斐尔·酷奇(Rafal Ku) 马雷克·罗戈任斯基(Marek Rogozis ...

  8. 《深入理解Elasticsearch(原书第2版)》一2.3.3 把查询模板保存到文件

    本节书摘来华章计算机<深入理解Elasticsearch(原书第2版)>一书中的第2章 ,第2.3.3节,[美]拉斐尔·酷奇(Rafal Ku) 马雷克·罗戈任斯基(Marek Rogoz ...

  9. 《深入理解Elasticsearch(原书第2版)》一第1章

    本节书摘来华章计算机<深入理解Elasticsearch(原书第2版)>一书中的第1章 ,[美]拉斐尔·酷奇(Rafal Ku) 马雷克·罗戈任斯基(Marek Rogoziski)著 张 ...

最新文章

  1. 搭建MVC及WebAPI项目框架时碰到的问题集合
  2. kubernetes之flannel 网络分析
  3. 为节省8亿做迁移,13亿记录出错赔偿29亿
  4. cuda 图片拆分_急需,PDF怎么拆分啊?
  5. ATOM使用的一点心得与技巧——在一个窗口打开多个项目
  6. 初识python: 生成器并行(做包子,吃包子)
  7. 一. 图模型(graphical model, GM)的表示
  8. latex在行末出现百分号的作用
  9. MySQL用命令行运行sql文件
  10. 数据治理方案技术调研 Atlas VS Datahub VS Amundsen
  11. 报 刊 集 锦(转载)
  12. 网页教程:为网站的Web Robot 设计路标
  13. 小妲己智能机器人要连接wifi吗_ZIB智伴机器人可以连WiFi吗 ZIB智伴机器人连接WiFi方法...
  14. python逆时针画圆_python 逆时针
  15. 2022-03微软漏洞通告
  16. ReSharper未按照预期路径安装后如何修改(Windows 找不到“C:\Program Files (x86)\JetBrains\Installations”。请检查拼写并重试)
  17. javascript 代码中的use strict是什么意思
  18. loadrunner的TPS和点击率HPS
  19. 关于hadoop集群常见的节点失联问题
  20. java spark yarn_Spark on yarn

热门文章

  1. Fiddler对手机抓包
  2. php教程链接,php自动给网址加上链接的方法,php网址链接方法_PHP教程
  3. oracle查看数据库剩余空间,Oracle 查看数据库空间使用情况
  4. 只有一个显示器但是显示两个显示器_小米34寸曲面显示器深度体验 办公体验极佳 但是还有个大弱点...
  5. java调用存储过程 sql server_Java中调用SQL Server存储过程示例
  6. java时间戳转calender_Java获取当前时间,时间戳转换为时间格式 | 学步园
  7. php的防csrf攻击,zblog php添加Token防止CSRF攻击
  8. php %3f,PHP
  9. Linux系统自启动脚本
  10. Requests 2.18.1文档