ES使用中遇到的坑

2023-11-13

1.ES分页超过10000条报错

es 默认采用的分页方式是 from+ size 的形式,是一种逻辑上的分页,在深度分页的情况下,采用from,to方式进行分页效率会非常的低,例如以下查询

1 GET /student/_doc/_search
2 {
3   "query":{
4     "match_all": {}
5   },
6   "from":5000,
7   "size":10
8 }

ES并不是单纯的查询5000-5010这10条数据,而是在各个分片上匹配排序并得到5010条数据,协调节点拿到这些数据再进行排序等处理,然后结果集中取最后10条数据返回。随着分页深度的加深,ES的分页效率会越来越低,甚至OOM。

ES为了性能默认情况下限制了分页的深度,如果不做任何配置,ES只能查询前10000条数据,也就是 max_result_window = 10000。如果分页到10000条数据以上,ES会报错。

解决方法:

  • 调大max_result_window的值
  • 使用scroll进行分页
  • 使用search_after进行分页(官方推荐)
2.ES 返回结果total始终是10000
      1 {
      2   "took" : 48,
      3   "timed_out" : false,
      4   "_shards" : {
      5     "total" : 1,
      6     "successful" : 1,
      7     "skipped" : 0,
      8     "failed" : 0
      9   },
     10   "hits" : {
     11     "total" : {
     12       "value" : 1000,
     13       "relation" : "eq"
     14     },
     15     "max_score" : null,
     16     "hits" : [
     17       {
     18         "_index" : "bank",
     19         "_type" : "_doc",
     20         "_id" : "0",
     21         "_score" : null,
     22         "_source" : {
     23           "account_number" : 0,
     24           "balance" : 16623,
     25           "firstname" : "Bradshaw"
     34         },
     35         "sort" : [
     36           0
     37         ]
     38       },

如上是是Es一次普通查询返回的结果集

  • hits 用来实际搜索结果集
  • hits.total 是包含与搜索条件匹配的文档总数信息的对象
  • hits.total.value 表示总命中计数的值(必须在hits.total.relation上下文中解释)

要注意的是hits.total.value返回的值不一定是准确的,默认情况下,hits.total.value是不确切的命中计数,在这种情况下,当hits.total.relation的值是eq时,hits.total.value的值是准确计数。当hits.total.relation的值是gte时,hits.total.value的值是不准确的。需要设置track_total_hits为true,才能使hits.total.value的结果准确

1 GET /student/_doc/_search
2 {
    "track_total_hits":true;
3   "query":{
4     "match_all": {}
5   },
6   "size":0
7 }

当然如要统计文档数量我们更推荐使用count,而不是通过hits.total.value来表示.

参数track_total_hits可以控制total值的准确性,可以设为false、true或正整数。

  • 当为false时,不再返回total计数,total始终为1;
  • 当为正整数时,表示精确的命中文档计数,例如为1000时,此时如果命中结果小于或等于1000时,value是精确的计数,relation是eq,如果命中的结果数大于了1000时,此时value等于1000,relation是gte,如果需要精确统计结果数,这个值要设置的很大或者设为true
  • 当track_total_hits设置为true时,hits.total.value的值始终是准确的但是会影响查询性能。
3.terms分桶聚合结果不准确

ES基于分布式,每一个搜索请求都是分发到所有的分片上单独处理,最后汇总结果。聚合也是这样操作。

在 Terms Aggregation 的返回中有两个特殊的数值

  • doc_count_error_upper_bound:被遗漏的 term 分桶包含的文档有可能的最大值,也就是没有在这次聚合中返回,但是可能存在的潜在聚合的值。
  • sum_other_doc_count: 处理返回结果 bucket 的 terms 以外,其他 terms 的文档总数(总数 -返回的总数),这次聚合中没有统计到的文档数。

因为ES为分布式部署,不同文档分散于多个分片,这样当聚合时,会在每个分片上分别聚合,然后由协调节点汇总结果后返回。聚合结果会按照value从高到低进行排序。terms聚合也可以指定一个size,表示返回聚合的数量,如果设置size为3,则表示返回value排名前三的结果,这时每个分片都只聚合了本分片中排名前三的桶。其他没有统计到的文档数由每个节点返回后,汇总为此元素。sum_other_doc_count显示多少,就表示有多少个文档没有参与此次聚合。所以terms聚合并不是准确的聚合

解决

  • 当数据量不大时,可以不设置分片,所有数据在一个分片上
  • 聚合时调大shard_size 参 数,降低 doc_count_error_upper_bound 来提升准确度默认shard_size = size *1.5 +10
  • size调大,提高聚合结果的数量,可以保证结果近似准确。
4.ES时间类型的查询和存储问题

在Elasticsearch内部,不论 date 是什么展示格式,所有date类型数据(时间字符串 or 时间戳等)在 Elasticsearch 内部存储时全部都会转换成 UTC时间戳(并且把时区也会计算进去),最后以milliseconds-since-the-epoch 作为存储的格式。date类型字段上的查询会在内部被转为对long型值的范围查询,查询的结果类型是字符串。

  • GMT:格林威治标准时间
  • UTC:世界协调时间
  • DST:夏日节约时间
  • CST:中国标准时间

具体细节参照博客https://blog.csdn.net/lijingjingchn/article/details/106925871

我们的项目中为了避免时区问题用到了两种方案

  • ES中Data类型的数据指定格式化方式,数据存入ES使用 字符串的日期时间,查询ES也直接使用字符串的日期时间

    PUT  test-date
    {
      "mappings": {
        "time": {
          "properties": {
            "date": {
              "type": "date",
              "format": "yyyy-MM-dd HH:mm:ss"
            }
          }
        }
      }
    }
    
    POST test-date/time/1
    {
        "date":"2017-09-15 14:50:16"
    }
    
    
    GET test-date/time/_search
    {
      "query":{
        "term": {
          "date": {
            "value": "2017-09-15 14:50:16"
          }
        }
      }
    }
    
  • ES的日期时间使用long类型的时间戳存储,日期时间类型的数据存入ES先用Java将其转为时间戳再存入ES。同样查询时也将日期时间转为时间戳再进行查询

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ES使用中遇到的坑 的相关文章

随机推荐

  • C++从入门到放弃之:C++ 模板之自制容器

    自制链表容器 1 include
  • DNS递归查询和迭代查询的区别

    1 递归查询 递归查询是由DNS 服务器主动帮主机查询的查询模式 在该模式下本地DNS 服务器接收到主机的请求 如果本地DNS 服务器没有存储相关的DNS 信息 那么该DNS 服务器会询问其他DNS 服务器 以此类推 最后不管成功与否 都将
  • 2020ciscn wp

    目录 1 签到电台 2 基于挑战码的双向认证 1 2 3 web Ezpo 4 基于挑战码的双向认证3 5 ISO9798 6 问卷调查 7 ez usb 8 login nomal 1 签到电台 操作内容 根据公众号提示 知道了模十的算法
  • SeleniumLibrary4.5.0 关键字详解(八)

    SeleniumLibrary4 5 0 关键字详解 八 库版本 4 5 0 库范围 全局 命名参数 受支持 简介 SeleniumLibrary是Robot Framework的Web测试库 本文档说明了如何使用SeleniumLibra
  • Zigbee协议栈(CC2530开发板) 修改发射功率

    Zigbee协议栈 CC2530开发板 修改发射功率 2010 12 07 15 11 43 分类 Zigbee 标签 zigbee 协议栈 发射功率 字号 订阅 CC2530 控制输出功率的寄存器是 TXPOWER 推荐功率设置 协议栈默
  • 矩阵求导——Numerator Layout & Denominator Layout

    突然想起这个问题了 刚刚看到有人在问某个的公式 自己闷头想了想居然都忘的差不多了 于是乎稍微整理一下供以后参考 其实 关于矩阵求导讲的最详细的还是wiki上的页面面http en wikipedia org wiki Matrix calc
  • 【janio】janio 官网 翻译 Janino 是一个超小、超快的 Java 编译器

    1 概述 翻译 http janino compiler github io janino janino as a 20compiler Janino 是一个超小 超快的 Java 编译器 Janino不仅可以像JAVAC一样将一组源文件编
  • Echarts特殊用法总结

    最近做了一个微信公众号项目 使用Echarts绘制降雨量曲线 水库水位及库容曲线 大坝断面监测等图表 通过查阅官方文档及示例 度娘 与Echarts的距离更近了一步 总结一下 不能直接在官网上找到答案的用法 有以下几处 x轴为value类型
  • JavaScript DOM和BOM

    目录 查找html元素 1 通过id 2 通过标签名 3 通过类名 DOM 1 创建动态的HTML内容 2 修改元素内容 3 改变HTML属性 4 改变css样式 DOM事件 DOM节点 1 添加HTML元素 2 删除HTML元素 浏览器对
  • nginx学习记录(一) 认识、了解

    本文记录个人学习nginx的学习笔记 方便自己日后查看 也希望各位大佬看到有什么不对可以指点一二 一 什么是nginx 基本介绍 Nginx 是一款轻量级的 Web 服务器 反向代理服务器 电子邮件 IMAP POP3 代理服务器 在BSD
  • 使用SVG绘制带箭头的线

  • 小程序实现小窗功能

    效果图 正常情况下 正常退出直播间后 可添加官方支持的小窗展示功能 小窗使用过程中 不会影响其他界面的使用 共存状态 用户端 主播段 异常情况下 1 当长时间悬挂小窗后 或者主播网络出问题的情况下 小窗会有加载loadding 点击进入直播
  • word中插入公式实现换行和对齐

    一 准备阶段 默认Unicode模式 进入公式编辑模式 输入 eqarray 紧接着按下空格键输入空格 如下 二 实现换行和对齐 将要编辑的公式输入到括号内 实现位置对齐 实现换行 三 结束公式编辑 输入完所有公式后 输入右括号 紧接着按下
  • 漂亮的表格样式(使用CSS样式表控制表格样式)

    依照WEB2 0风格 设计了几个表格样式 希望大家喜欢 WEB2 0提倡使用div开布局 但不是要完全放弃使用表格 表格在数据展现方面还是不错的选择 现在使用介绍使用CSS样式表来控制 美化表格的方法 lt html xmlns http
  • 蓝桥杯嵌入式创建第一个工程(点亮led灯)

    蓝桥杯嵌入式创建第一个工程 点亮led灯 一 keil导入stm32G431RX板级芯片包 1 1 下载板级芯片包 1 2 导入芯片包 1 2 1 我们首先打开keil 点击Pack installer 如图 1 2 2 然后选中file
  • arm基础知识

    目录 arm基础知识 谈谈对嵌入式的理解 计算机基本理论 计算机的组成 指令的解析 编译原理 ARM相关知识介绍 1 认识ARM ARM含义 架构 内核 SOC ARM的发展历史 指令集 ARM公司产品分布 ARM体系结构 ARM v8 A
  • 机器学习笔记:李宏毅ChatGPT Finetune VS Prompt

    1 两种大语言模型 GPT VS BERT 2 对于大语言模型的两种不同期待 2 1 专才 2 1 1 成为专才的好处 Is ChatGPT A Good Translator A Preliminary Study 2023 Arxiv
  • 华为OD机试 - 英文输入法(Java)

    题目描述 主管期望你来实现英文输入法单词联想功能 需求如下 依据用户输入的单词前缀 从已输入的英文语句中联想出用户想输入的单词 按字典序输出联想到的单词序列 如果联想不到 请输出用户输入的单词前缀 注意 英文单词联想时 区分大小写 缩略形式
  • requests库学习

    requests库学习 requests快速上手 http 2 python requests org zh CN latest user quickstart html Requests库是用来发送HTTP请求 接收HTTP响应的一个Py
  • ES使用中遇到的坑

    1 ES分页超过10000条报错 es 默认采用的分页方式是 from size 的形式 是一种逻辑上的分页 在深度分页的情况下 采用from to方式进行分页效率会非常的低 例如以下查询 1 GET student doc search