Elasticsearch 使用误区之四——不合理的使用 track_total_hits

news2024/9/23 5:30:12

0、企业级实战问题

在使用 Elasticsearch 进行搜索时,我们常常关心匹配查询的文档总数而将 track_total_hits 设置为 true,如下截图所示,在数据量非常大的情况下这种检索导致的问题是:查询特别慢,聚合会更慢!

5af2cfb7cc92103eb5832b901bf5e5a2.png

那么问题来了:

  • track_total_hits 引入的背景是什么?哪个版本才有的?

  • track_total_hits 含义是什么?

  • track_total_hits 什么时候需要设置 true ?

  • track_total_hits 什么时候设置 false?

  • track_total_hits 什么时候设置值?

  • track_total_hits 如何使用?

基于这些问题,本文逐步展开探讨。

1、track_total_hits 引入背景

在搜索引擎领域中,性能与准确性一直是开发者需要平衡的两个关键点。随着 Lucene 8(2019年4月前后)的推出,我们看到了几项重要的优化,这些优化不仅提升了搜索速度,还改变了我们获取搜索结果的方式。

特别是关于 track_total_hits 参数的变化,它直接关系到查询结果的性能表现和命中数的准确性。

Elasticsearch 在 7.0 版本集成了 Lucene 8 并引入这个特性。

https://www.elastic.co/guide/en/elasticsearch/reference/7.0/breaking-changes-7.0.html

track_total_hits 参数控制着 Elasticsearch 在返回查询结果时,如何计算匹配文档的总数。

过去,Elasticsearch 总是精确地计算总命中数,这意味着它必须遍历所有匹配的文档。显然,处理大量文档时代价高昂。

2、 track_total_hits 的工作原理

  • 默认行为:track_total_hits 设置为 false。

在Lucene 8中,如果不设置 track_total_hits,Elasticsearch 将默认使用 WAND 优化(WAND 优化算法本质——通过跳过不可能产生高分的文档来加快查询速度)。

这意味着当查询结果的总命中数超过一定阈值时(默认:10,000),Elasticsearch不再返回精确的命中数,而是返回一个下限值。

  • 准确计数:track_total_hits 人为修改设置为 true。

如果用户确实需要精确的命中数,可以通过将track_total_hits设置为 true 来强制Elasticsearch计算所有匹配文档的总数。然而,这会禁用WAND优化,从而导致性能下降(前文截图说慢,很大可能就是这里的原因)。

  • 设置阈值:用户自己设置 track_total_hits 阈值大小。

用户自己设置track_total_hits 为整数值(例如1000)时,如果匹配的文档总数超过了这个阈值,Elasticsearch 会返回的下限值就是我们设置的阈值本身,即1000,并指示命中数大于或等于1000。

如果这里有不理解,没关系,继续往后看,一会我们完整演示一遍。

3、 track_total_hits 设置后,和老版本(6及之前)显示不同点

当 track_total_hits 设置为默认值或较小的数值时,响应中的hits.total字段将包含一个对象,该对象包括命中数的值和关系,例如:

"hits": {
    "total": {
      "value": 10000,
      "relation": "gte"
    },
  • 当 relation 为 gte 时,表示实际的命中数大于或等于这个值。

  • 当 relation 为eq时,表示命中数是精确的。

除此之外,没有别的情况了。

4、拿真实样例数据演示一把

基础索引数据 test_index_0618, 共 100万条文档。

940a4612ac9b5ff247760180d3d39dc3.png

a14efc7b367f64361e7974c897e33059.png

4.1 track_total_hits 默认情况

如前所述,如果不做设置,默认支持最大文档数为 10000。

9f1cc949666c8134c098fc08a86d9bd7.png

通过执行结果可以看出,召回了 10000条数据,relation 代表确切含义:真实数据大于等于 10000。

4.2 track_total_hits 设置为 true

如果我们把  track_total_hits 设置为 true,依然执行 4.1 相同的检索语句。

9162e965c9ad46ffb0cc556d9624bd3a.png

执行结果可以看出,显示了真实文档数 100万,relation 是 “eq” 代表相等。

这个示例,也间接告诉我们:企业级实战环节,如果我们有复杂的检索、聚合操作,且数据量级也巨大(千万、亿、十亿甚至更多),如果track_total_hits 设置为 true,真的有可能产生检索效率极低的“灾难性”后果(相同硬件资源的前提下,数据量越大,检索可能越慢的共识大家都很清楚)。

4.3 track_total_hits 设置为给定值

这里的给定值,本质上是我们要修改的默认的阈值大小。比如这里,我们设置为 1000。

ad44875b49c77d597b98428a96c9b7cb.png

如结果展示,我们设置多大,最后召回数据就是多少。这个在真实业务场景中有选择的使用即可。

4.4 track_total_hits 设置为false

在一些性能敏感的场景下,我们可能根本不需要知道总命中数。

在这种情况下,我们可以将track_total_hits设置为false,以提高查询速度。

a21b15ef82b21afb2c4344031dea3f7e.png

如果所示,在这种情况下,返回结果中没有 total.value,意味着Elasticsearch并未计算总命中数,从而节省了大量的计算资源。

5、 track_total_hits 的性能权衡

track_total_hits 参数的核心在于它允许我们在命中数的准确性和查询性能之间做出权衡。

具体而言,如第4部分演示所示,这里总结如下表所示。

参数设置含义应用场景

track_total_hits: true

精确计算所有匹配文档的总数

适用于需要确切命中数的场景,但会牺牲查询性能。

track_total_hits: 1000

精确计算匹配文档的总数,直到达到指定上限(如1000)

在大部分情况下只关心部分准确的命中数,如需要快速查询并展示前几个结果。

track_total_hits: false

完全忽略总命中数的计算

对命中数不敏感且更关注查询速度的场景,例如仅需快速返回文档内容而不关注总命中数。

再次提醒:设置 track_total_hits 为 true时,会禁用 Max WAND 优化,这可能显著影响查询性能。因此,除非确有必要,否则建议谨慎使用。

6、总结

理解并合理使用track_total_hits参数,能够帮助我们在Elasticsearch中实现更高效的查询,同时避免不必要的性能开销。

其实所有的参数都建议我们抠一下细节后,必要时做一下性能测试后再应用到实战环节。

参考

https://github.com/elastic/elasticsearch/issues/33028

https://www.elastic.co/cn/blog/whats-new-in-lucene-8

https://www.elastic.co/guide/en/elasticsearch/reference/7.0/breaking-changes-7.0.html

https://www.elastic.co/guide/en/elasticsearch/reference/8.15/search-your-data.html#track-total-hits

更多推荐

Elasticsearch 使用误区之一——将 Elasticsearch 视为关系数据库!

  Elasticsearch 使用误区之二——频繁更新文档

  Elasticsearch 使用误区之三——分片设置不合理

   《一本书讲透 Elasticsearch》读者群的创新之路

38fc6ed9fb1ab1b12381bd73e01a2506.png

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

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

elastic6.cn——ElasticStack进阶助手

35553264e1c457c4d7536110c703fbcb.gif

抢先一步学习进阶干货!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2057365.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RKNN在转换过程中的均值和方差设置问题

为什么ONNX转RKNN要匹配均值和方差? 因为不匹配精度会下降!!! 一般的类似于YOLO模型 YOLO模型在ONNX转RKNN时rknn.config设置为 一些其他模型将数据送入模型时会进行前处理,前处理会设置均值和方差,则在转…

【Nginx】实现 FastCGI

为什么会有 FastCGI ? CGI 协议虽然解决了语言解析器和 Web Server 之间通讯的问题,但是它的效率很低,因为 Web Server每收到一个请求都会创建一个CGI 进程, PHP 解析器都会解析 php.ini 文件,初始化环境&#xff0c…

LCP142 环形链表[leetcode-7]

LCP142 环形链表 先上结果 前排提醒,本文有两种解法,和原理分析 给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次…

数据结构与算法 - 设计

1. LRU缓存 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值&#xff0…

0819、0820梳理及一些面试题梳理

一、抓包分析 二、HTTP服务器 三、动态库与静态库 四、一些面试题 指针数组和数组指针的区别:指针数组本质是一个数组,只是数组中存储的是指针变量。数组指针存储的是该数组的起始地址,对该指针来说每偏移一个单位就是偏移了一整个数组的地…

如何寻找专业精密机械零件代加工工厂

在现代工业生产中,精密机械零件的加工质量直接关系到产品的性能和可靠性。因此,寻找一家专业的精密机械零件代加工工厂至关重要。以下时利和整理分享的一些关于寻找专业精密机械零件代加工工厂的关键步骤和要点,帮助你找到合适的合作伙伴。 首…

想投资现货黄金?在TMGM开户需要多少钱?

最近,越来越多的人开始关注黄金投资,希望通过黄金来对冲风险、保值增值。而选择一家可靠的交易平台是进行黄金投资的第一步。TMGM作为全球知名的外汇交易商,也为投资者提供了黄金交易服务。那么,在TMGM开户投资黄金,需…

尚硅谷VUE项目实战,前端项目-尚品汇2

尚硅谷VUE项目实战,前端项目-尚品汇2 1、路由传参 2、重写push

数字转化为千位符形式, 百分比形式

Intl.NumberFormat 千位符: function formatAsRMB(num){return new Intl.NumberFormat(zh-CN,{style: decimal, //将数字格式化为十进制数currency: CNY, // 货币为人民币minimumFractionDigits: 0 // 表示不显示小数部分}).format(num)}const number 12345678co…

【C++进阶学习】第十四弹——特殊类设计——探寻各种情况下类的应用

前言: C类是C很重要的一个部分,在很多应用场景中都发挥着十分重要的作用,今天我们来讲解几个特殊场景下类的应用 目录 一、特殊类:只能在栈/堆上创建对象 1. 只在栈上创建对象 2. 只在堆上创建对象 二、特殊类:不能…

8.20 QT

1.思维导图 2. 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTime> #include <QTimerEvent> #include <QTextToSpeech>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidge…

Zookeeper中 Server 服务器的四种工作状态详解

Zookeeper中 Server 服务器的四种工作状态详解 1. LOOKING2. FOLLOWING3. LEADING4. OBSERVING&#xff08;3.3.0及以后版本&#xff09; &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; ZooKeeper集群中的服务器主要存在以下四种工作状态&a…

32位入门级MCU(ARM Cortex-M3内核)STM32F103系列

推荐: 32位入门级MCU(ARM Cortex-M3内核)中的六边形战士——STM32F103系列 为什么MCU中需要ADC模块 原创 IPBrain平台君 集成电路大数据平台 2024年08月19日 19:18 北京 自从平台君发布了几期关于MCU的文章之后,后台有很多小伙伴们留言。其中有位读者问平台君:平台君,…

python构建一个web程序

from flask import Flaskapp Flask(__name__)app.route(/) def hello_world():return 欢迎来到我的Python Web程序!if __name__ __main__:app.run(debugTrue)1、安装flask D:\Users\USER\PycharmProjects\pythonProject1\p01>pip install flask WARNING: Ignoring invalid…

LLM才硬件(显存)需求

参考&#xff1a; https://www.hardware-corner.net/guides/computer-to-run-llama-ai-model/ GitHub - hiyouga/LLaMA-Factory: Efficiently Fine-Tune 100 LLMs in WebUI (ACL 2024) 直观的一个表&#xff1a;

多模态学习Multimodal Learning:人工智能中的多模态原理与技术介绍初步了解

多模态学习&#xff08;Multimodal Learning&#xff09;是机器学习中的一个前沿领域&#xff0c;旨在综合处理和理解来自不同模态的数据。模态可以包括文本、图像、音频、视频等。随着数据多样性和复杂性增加&#xff0c;多模态学习在自然语言处理、计算机视觉、语音识别等领域…

存储和传输/寻找大端字节序/有哪款MCU或MPU是真支持大端?

文章目录 概述ARM基础ARM 不生产芯片ARM分类和命名ARM指令集和架构ARM架构和内核ARM内核和芯片其他处理器架构 在手册中找寻字节序的踪迹ST 32 MCU 没有大端&#xff1f;Cortex-M 系列Cortex-A 系列Cortex-R 系列小结 芯片外设支持大端字节序DMAC 支持大端字节序的情况CRC 支持…

SpringBoot接入高德地图猎鹰轨迹服务API

SpringBoot接入高德地图猎鹰轨迹服务API 一、AP文档 猎鹰轨迹服务API文档 二、页面图 1、需登录账号&#xff0c;申请对应的应用key值 三、代码部分&#xff1a; 1、控制层 RestController RequestMapping("/gdTrack") public class TrackController {private …

VS Code开发C#(.NET)之快速入门

本篇快速介绍在VS Code中开发C#的完整说明和示例&#xff1a; 环境准备 安装VS Code&#xff1a; 前往Visual Studio Code官网 下载并安装VS Code。 安装.NET SDK&#xff1a; C#是基于.NET框架的&#xff0c;因此需要安装 .NET SDK。 前往 .NET官网 下载并安装适用于操…

【微信小程序】自定义组件 - 插槽

1. 什么是插槽 2. 单个插槽 在小程序中&#xff0c;默认每个自定义组件中只允许使用一个 进行占位&#xff0c;这种个数上的限制叫做单个插槽。 3. 启用多个插槽 在小程序的自定义组件中&#xff0c;需要使用多 插槽时&#xff0c;可以在组件的 .js 文件中&#xff0c;通过…