一、查询总数

1.  ES 查询 hits 统计总数不准?

当我们使用 ES 的时候,有时会比较关心匹配到的文档总数是多少,所以在查询得到结果后会使用 hits.total.value 这个值作为匹配的总数,如下

图一

说明:这是因为,es官方默认限制索引查询最多只能查询10000条数据。

2.  track_total_hits

平常数据量不大的情况下,这个数值没问题。但是当超出 10000 个数据量的时候,这个 value 将不会增长了,固定为 10000。这个时候很显然数量统计就不准了。

ES 为我们准备了这样一个参数来开启精确匹配 track_total_hits

这个时候返回值将是精确的:

图二

3.  track_total_hits的使用场景

如果你的业务需求在超过 10000 这个阈值之后就不需要精准的计算的话,就不需要设置该值,毕竟匹配大量的文档是一个成本较高的操作,同样的如果你并不需要统计数量,那么将该值设置为 false "track_total_hits": false 也是一种优化检索效率的操作。

4.  hits.total.relation

通过图一和图二,可以发现设置 track_total_hits 为 true 的时候返回 relation 的值是不一样的,gte 表示 hits.total.value 是查询匹配总命中数的上限。 eq 则表示hits.total.value 是准确计数。

因此,我们可以通过设置 track_total_hits 为整数,来自定义上限如:

二、查询数据

1.  查询超过10000条数据,开始报错

上面解决了需要统计超过10000条数据总数的问题,但是在查询具体数据的时候依然存在类似的问题。es官方默认限制索引查询最多只能查询10000条数据,查询第10001条数据开始就会报错:

result window is too large, from + size must be less than or equal to

解决方案:

1)第一种办法:在kibana中执行,解除索引最大查询数的限制

put _all/_settings
{"index.max_result_window":200000
}

_all表示所有索引,针对单个索引的话修改成索引名称即可。

2)第二种办法:在创建索引的时候加上

1 "settings":{
2   "index":{
4      "max_result_window": 500000
5    }
7 }

三、深度分页

做分页查询的时候,我们需要考虑两个问题

  • 性能要求,在硬件和查询效率中作出权衡
  • 对大部分请求来说,都不会超过10000条,即不需要深度分页,当需要请求超过10000条时,就需要考虑我们的查询语句是否恰当

下面有几种分页方式:

1、方式一: from+size浅分页

"浅"分页可以理解为简单意义上的分页。它的原理很简单,就是查询前20条数据,然后截断前10条,只返回10-20的数据。这样其实白白浪费了前10条的查询。

 1 GET test_alias/_search2 {3 "query": {4     "match_all": {5     }6   },7   "sort": [8     {9       "add_time": {
10         "order": "desc"
11       }
12     }
13   ],
14   "from":0,
15   "size": 2
16 }

其中,from定义了目标数据的偏移值,size定义当前返回的数目。默认from为0,size为10,即所有的查询默认仅仅返回前10条数据。

from/size的原理

因为es是基于分片的,假设有5个分片,from=100,size=10。则会根据排序规则从5个分片中各取回100条数据数据,然后汇总成500条数据后,选择最后面的10条数据。

做过测试,越往后的分页,执行的效率越低。总体上会随着from的增加,消耗时间也会增加。而且数据量越大,就越明显。

说明:from+size查询在10000-50000条数据(1000到5000页)以内的时候还是可以的,但是如果数据过多的话,就会出现深分页问题。

2、方式二: scroll深分页

为了解决上面的问题,elasticsearch提出了一个scroll滚动的方式。

scroll 类似于sql中的cursor,使用scroll,每次只能获取一页的内容,然后会返回一个scroll_id。根据返回的这个scroll_id可以不断地获取下一页的内容,所以scroll并不适用于有跳页的情景。

2.1 参数说明:

  • scroll=5m表示设置scroll_id保留5分钟可用。
  • size决定后面每次调用_search搜索返回的数量

2.2  scroll删除

根据官方文档的说法,scroll的搜索上下文会在scroll的保留时间截止后自动清除,但是我们知道scroll是非常消耗资源的,所以一个建议就是当不需要了scroll数据的时候,尽可能快的把scroll_id显式删除掉。

1)清除指定的scroll_id:

DELETE _search/scroll/DnF1ZX...

2)清除所有的scroll:
    DELETE _search/scroll/_all

然后我们可以通过数据返回的_scroll_id读取下一页内容,每次请求将会读取下10条数据,直到数据读取完毕或者scroll_id保留时间截止。

说明:scroll 的方式,官方的建议不用于实时的请求(一般用于数据导出),因为每一个 scroll_id 不仅会占用大量的资源,而且会生成历史快照,对于数据的变更不会反映到快照上。

3、方式三:search_after 深分页

search_after是ES5.0 及之后版本提供的新特性,search_after有点类似scroll,但是和scroll又不一样,它提供一个活动的游标,通过上一次查询最后一条数据来进行下一次查询。

比如第一次查询如下:

注意到返回结果中有一个sort字段,所以下一次查询的时候,只需要将本次查询最后一条数据中的排序字段加入查询即可:

实现原理:

search_after 分页的方式是根据上一页的最后一条数据来确定下一页的位置,同时在分页请求的过程中,如果有索引数据的增删改查,这些变更也会实时的反映到游标上。

说明:

  • 为了找到每一页最后一条数据,每个文档必须有一个全局唯一值,官方推荐使用 _uid 作为全局唯一值,其实使用业务层的 id 也可以。
  • 说明:使用search_after查询需要将from设置为0或-1,当然也可以不写。

需要注意的是:

1)sort字段的选择

如果search_after中的关键字为***,那么***123的文档也会被搜索到,所以在选择search_after的排序字段时需要谨慎,可以使用比如文档的id或者时间戳等。另外,search_after并不是随机的查询某一页数据,而是并行的滚屏查询;search_after的查询顺序会在更新和删除时发生变化,也就是说支持实时的数据查询。

2)无法跳页请求

因为每一页的数据依赖于上一页最后一条数据,所以无法跳页请求。

4、方式四: 由前端传入上次查询的最小ID

由于业务需要,我这边实现的分页列表由前端配合一起完成,这样也解决了跳页的问题,供参考:

 1 <?php2 3 class Test4 {5 6     public function queryBaiduJobList(array $fileds, int $minId, int $limit)7     {8         // 为了解决es查询默认1w条的上限,由前端传入上一次查询返回列表中最小id:minId9         $query = JobParams::build()
10             ->term('is_check', 1)
11             ->select($fileds)
12             ->trackHits(true)
13             ->sort('id')
14             ->limit($limit);
15
16         if ($minId) {
17             $query = $query->range('id', ['<', $minId]);
18         }
19
20         return $this->all($query);
21     }
22 }

es查询-统计总数以及深度分页相关推荐

  1. ES 查询示例 搜索 分组 去重 分页 排序

    es 查询示例 搜索 分组 去重 分页 排序 java 语句 @Autowiredprivate static RestHighLevelClient client;@PostConstructpub ...

  2. PageHelper关联查询 统计总数问题

    项目场景: 业务:查询功能,需要关联多张表,为一对多或多对多. 需求:要求分页,分页统计总数. 使用技术:Mybatis,PageHelper 问题描述 正常查询一张表的情况下,官方推荐: //获取第 ...

  3. 【ES】ES 运用search_after来进行深度分页

    1.概述 ES本身是支持分页查询的,使用方式跟MySQL非常类似: from: Indicates the number of initial results that should be skipp ...

  4. ElasticSearch之处理深度分页

    ElasticSearch之处理深度分页 一.常规分页 二.scroll分页 三.search_after 在ES中实现分页的方法有三种,我们逐个分析一下他们的优缺点. 一.常规分页 在ES中,我们可 ...

  5. ElasticSearch 深度分页详解

    来源 | OSCHINA 社区 作者 | 京东云开发者-何守优 原文链接:https://my.oschina.net/u/4090830/blog/5593128 1 前言 ElasticSearc ...

  6. ES深度分页查询详解

    一.ES支持的三种分页查询方式 From + Size 查询 Scroll 遍历查询 Search After 查询 说明: 官方已经不再推荐采用Scroll API进行深度分页.如果遇到超过1000 ...

  7. Mybatisplus 分页查询时,禁止自动统计总数

    1.分页插件 使用 Mybatisplus 时 ,我们使用 PaginationInnerInterceptor 作为分页插件,它会帮助我们进行分页,查询总数. @Configuration @Map ...

  8. ElasticSearch 分页查询及深度分页原理与实现

    查询流程 查询阶段 在初始化查询阶段(query phase),查询被向索引中的每个分片副本(原本或副本)广播.每个分片在本地执行搜索并且建 立了匹配 document 的优先队列(priority ...

  9. 上亿数据怎么玩深度分页?兼容MySQL + ES + MongoDB

    面试题 & 真实经历 面试题:在数据量很大的情况下,怎么实现深度分页? 大家在面试时,或者准备面试中可能会遇到上述的问题,大多的回答基本上是分库分表建索引,这是一种很标准的正确回答,但现实总是 ...

最新文章

  1. 悠然乱弹:聊聊模块化
  2. python 散点图_Python绘制散点图
  3. KPCR:CPU控制区(Processor Control Region)
  4. 【图像处理】——傅里叶变换、DFT以及在图像上的应用
  5. java与java ee_RxJava + Java8 + Java EE 7 + Arquillian =幸福
  6. java 递归从子节点删除父节点_LeetCode450. 删除二叉搜索树中的节点
  7. Hash (散列,哈希)
  8. [视频]Silverlight for Windows Phone 7基本开发过程以及Push Button控件的使用
  9. c# 网口相机可以通过_双网口硬盘录像机怎么设置?录像机连接GB28181公安专网步骤指导...
  10. iOS9 开发新特性 Spotlight使用
  11. Android手机使用Windows应用,微软宣布在你的手机应用上运行安卓APP功能向Windows 10稳定版提供...
  12. springboot 配置过滤器不起作用的原因
  13. 正则表达式匹配第一个单个字符
  14. 孪生网络图像相似度_图像相似度比对
  15. 多多客id是什么意思_拼多多skuid是什么意思(关于sku编码的详细介绍)
  16. Win10+Android+夜神安卓模拟器 搭建ReactNative开发环境
  17. 好未来 Dolphin-儿童口语表达能力AI自动评测:顶尖AI算法技术与教育理念的有机结合 | 百万人学AI评选
  18. 如何建立简易Rss源
  19. RabbitMq中的mandatory
  20. 智能称体脂称实现(基本原理解释篇)

热门文章

  1. VSCode快捷键冲突?关掉微软拼音的简繁体切换热键即可
  2. 使用HMMER搜索PFam
  3. python kfold交叉验证_KFold交叉验证
  4. 求n的阶乘的算法框图_当代程序员必备技能(算法)之:递归详解 - Java斗帝之路...
  5. 弱网测试NEWT-----Network Emulator for Windows Toolkit
  6. Fast-MoCo: Boost Momentum-based Contrastive Learning with Combinatorial Patches
  7. python 路边停车
  8. Python爬虫爬取手机APP的数据
  9. 用python处理水仙花数
  10. js indexOf使用及注意事项以及数组使用indexOf