Elasticsearch中的分页查询限制和近似去重统计
Elasticsearch
前言
最近工作中用到了Elasticsearch,但是遇到几个挺坑的点,还是记录下。
深度分页的问题
es中的普通的查询from+size,存在查询数量的10000条限制。
index.max_result_window
The maximum value of from + size for searches to this index. Defaults to 10000. Search requests take heap memory and time proportional to from + size and this limits that memory. See Scroll or Search After for a more efficient alternative to raising this.
es为了减少内存的使用,限制了内存中索引数据的加载,默认10000。也就是
from 10000 size 1
这样的查询就是不行的,将会报错
Result window is too large, from + size must be less than or equal to:[10000] but was [10500]. See the scroll api for a more efficient way to requestlarge data sets. This limit can be set by changing the[index.max_result_window] index level parameter
如何解决
修改默认值
通过设置index 的设置参数max_result_window的值,来改变查询条数的限制。
curl -XPUT http://127.0.0.1:9200/book/_settings -d '{ "index" : { "max_result_window" : 200000000}}'
使用search_after方法
例子可参考官方https://www.elastic.co/guide/en/elasticsearch/reference/6.8/search-request-search-after.html
如何使用呢,就是设置一个全局唯一的字段,然后在查看的时候加上这个字段的排序。这样第二次查询,search_after第一次查询最后一条的对应的唯一值的值。有点绕哈,看例子
GET twitter/_search
{
"size": 10,
"query": {
"match" : {
"title" : "elasticsearch"
}
},
"sort": [
{"accessId": "asc"}
]
}
比如我的accessId是全局唯一,并且自增的,第二次查询search_after最新的accessId就好了
GET twitter/_search
{
"size": 10,
"query": {
"match" : {
"title" : "elasticsearch"
}
},
"search_after": [10],
"sort": [
{"accessId": "asc"}
]
}
后面的查询依次类推
scroll 滚动搜索
scroll 查询可以用来对Elasticsearch有效地执行大批量的文档查询,而又不用付出深度分页那种代价。
游标查询允许我们 先做查询初始化,然后再批量地拉取结果。 这有点儿像传统数据库中的cursor 。
游标查询会取某个时间点的快照数据。查询初始化之后索引上的任何变化会被它忽略。它通过保存旧的数据文件来实现这个特性,结果就像保留初始化时的索引 视图 一样。
深度分页的代价根源是结果集全局排序,如果去掉全局排序的特性的话查询结果的成本就会很低。游标查询用字段_doc来排序。 这个指令让 Elasticsearch仅仅从还有结果的分片返回下一批结果。
启用游标查询可以通过在查询的时候设置参数 scroll的值为我们期望的游标查询的过期时间。游标查询的过期时间会在每次做查询的时候刷新,所以这个时间只需要足够处理当前批的结果就可以了,而不是处理查询结果的所有文档的所需时间。 这个过期时间的参数很重要,因为保持这个游标查询窗口需要消耗资源,所以我们期望如果不再需要维护这种资源就该早点儿释放掉。设置这个超时能够让Elasticsearch在稍后空闲的时候自动释放这部分资源。
GET /old_index/_search?scroll=1m // 设置查询窗口一分钟
{
"query": { "match_all": {}},
"sort" : ["_doc"], // 使用_doc字段排序
"size": 1000
}
这个查询的返回结果包括一个字段_scroll_id,它是一个base64编码的长字符串 。现在我们能传递字段_scroll_id到_search/scroll查询接口获取下一批结果:
GET /_search/scroll
{
"scroll": "1m", // 时间
"scroll_id" : "cXVlcnlUaGVuRmV0Y2g7NTsxMDk5NDpkUmpiR2FjOFNhNnlCM1ZDMWpWYnRROzEwOTk1OmRSamJHYWM4U2E2eUIzVkMxalZidFE7MTA5OTM6ZFJqYkdhYzhTYTZ5QjNWQzFqVmJ0UTsxMTE5MDpBVUtwN2lxc1FLZV8yRGVjWlI2QUVBOzEwOTk2OmRSamJHYWM4U2E2eUIzVkMxalZidFE7MDs="
} // scroll_id是上次返回的
之后的查询依次类推
这个游标查询返回的下一批结果。 尽管我们指定字段size的值为1000,我们有可能取到超过这个值数量的文档。 当查询的时候, 字段 size 作用于单个分片,所以每个批次实际返回的文档数量最大为size * number_of_primary_shards。
es中的近似聚合
对于es来讲,其中的去重计数。是个近似的值,不像mysql中的是精确值,存在5%的误差,不过可以通过设置precision_threshold来解决少量数据的精准度
GET /cars/transactions/_search
{
"size" : 0,
"aggs" : {
"distinct_colors" : {
"cardinality" : {
"field" : "color",
"precision_threshold" : 100 // precision_threshold 接受 0–40,000 之间的数字,更大的值还是会被当作 40,000 来处理。
}
}
}
}
示例会确保当字段唯一值在 100 以内时会得到非常准确的结果。尽管算法是无法保证这点的,但如果基数在阈值以下,几乎总是100%正确的。高于阈值的基数会开始节省内存而牺牲准确度,同时也会对度量结果带入误差。
对于指定的阈值,HLL的数据结构会大概使用precision_threshold * 8字节的内存,所以就必须在牺牲内存和获得额外的准确度间做平衡。
在实际应用中,100的阈值可以在唯一值为百万的情况下仍然将误差维持5%以内。
总结
当我们选型es时候,要充分考虑到上面的几点。
Elasticsearch中的分页查询限制和近似去重统计的更多相关文章
- Elasticsearch中的Term查询和全文查询
目录 前言 Term 查询 exists 查询 fuzzy 查询 ids 查询 prefix 查询 range 查询 regexp 查询 term 查询 terms 查询 terms_set 查询 t ...
- mongo中的分页查询
/** * @param $uid * @param $app_id * @param $start_time * @param $end_time * @param $start_page * @p ...
- ssh框架中的分页查询
ssh中的分页查询是比较常用的,接下来我用代码来介绍如何实现一个分页查询 首先建立一个Model用来储存查询分页的信息 package com.haiziwang.qrlogin.utils; imp ...
- ElasticSearch中的简单查询
前言 最近修改项目,又看了下ElasticSearch中的搜索,所以简单整理一下其中的查询语句等.都是比较基础的.PS,好久没写博客了..大概就是因为懒吧.闲言少叙书归正传. 查询示例 http:// ...
- Elasticsearch from/size-浅分页查询-深分页 scroll-深分页search_after深度查询区别使用及应用场景
Elasticsearch调研深度查询 1.from/size 浅分页查询 一般的分页需求我们可以使用from和size的方式实现,但是这种的分页方式在深分页的场景下应该是避免使用的.深分页的页次增加 ...
- java使用插件pagehelper在mybatis中实现分页查询
摘要: com.github.pagehelper.PageHelper是一款好用的开源免费的Mybatis第三方物理分页插件 PageHelper是国内牛人的一个开源项目,有兴趣的可以去看源码,都有 ...
- 怎样在 Akka Persistence 中实现分页查询
在 Akka Persistence 中,数据都缓存在服务内存(状态),后端存储的都是一些持久化的事件日志,没法使用类似 SQL 一样的 DSL 来进行分页查询.利用 Akka Streams 和 A ...
- 关于在elasticSearch中使用聚合查询后只显示10个bucket的问题
先看下面es查询语句 { "size": 0, "aggs" : { "all_articleId" : { "terms&quo ...
- ElasticSearch—分页查询
ElasticSearch查询—分页查询详解 Elasticsearch中数据都存储在分片中,当执行搜索时每个分片独立搜索后,数据再经过整合返回.那么,如何实现分页查询呢? 按照一般的查询流程来说,如 ...
- 在Elasticsearch中查询Term Vectors词条向量信息
这篇文章有点深度,可能需要一些Lucene或者全文检索的背景.由于我也很久没有看过Lucene了,有些地方理解的不对还请多多指正. 更多内容还请参考整理的ELK教程 关于Term Vectors 额, ...
随机推荐
- WebService rwsp:NoRunningCommunicationPointAvailable
SoapUI 调WebService 报 No running communication point is configured to process this request. 错误 检查入参是否 ...
- 【设计模式】分享 Java 开发中常用到的设计模式(一)
分享 Java 开发中常用到的设计模式(一) 前言 不知道大家在开发的时候,有没有想过(遇到)这些问题: 大家都是按需要开发,都是一个职级的同事,为什么有些人的思路就很清晰,代码也很整洁.易懂:而自己 ...
- 使用 FHE 实现加密大语言模型
近来,大语言模型 (LLM) 已被证明是提高编程.内容生成.文本分析.网络搜索及远程学习等诸多领域生产力的可靠工具. 大语言模型对用户隐私的影响 尽管 LLM 很有吸引力,但如何保护好 输入给这些模型 ...
- Codeforces Round #624 (Div. 3) (A~D,CD Good)
比赛链接:Here 1311A. Add Odd or Subtract Even 签到题, \(a > b\) 时必须做做减法,如果差值为偶数的话只需要 \(1\) 次不然做一次减法后再做一次 ...
- Codeforces Round #716 (Div. 2) A ~ D 个人题解
补题链接:Here 1514A. Perfectly Imperfect Array 题意:给定长度为 \(n\) 的 \(a\) 序列,请问是否存在子序列积不存在平方根 思路:子序列的话,一个元素也 ...
- 【驱动】SPI驱动分析(二)-SPI驱动框架
SPI驱动框架 SPI驱动属于总线-设备-驱动模型的,与I2C总线设备驱动模型相比,大体框架是一样,他们都是实际的总线.总体框架如下图所示: 从上到下,分为三层,用户空间,内核空间,和硬件层. 用户空 ...
- prefer-rest-params
使用剩余参数代替 arguments (prefer-rest-params) 剩余参数来自于ES2016.可以在可变函数中使用这个特性来替代arguments变量.arguments没有Array. ...
- jQuery位置 内容 大小 属性 文档的操作
1. 位置 1. offset() 2. position() 2. 大小 1. 内容(content)>内填充(padding)>边框(border)>外边距(margin) 2. ...
- Java求一个集合的所有子集
转载请注明出处: 求一个集合的所有子集表示从一个集合当中,任取任意项或不取,所能得到的所有结果,比如有一个集合{a,b,c,d},那么{a,b}, {b, d}等都是它的子集,空集也是它的子集, 一个 ...
- AXI Channel
AXI Channel axi与ahb不同就是分为不同的channel write address channel - 表明一个transaction基本的属性,包含本次传输的地址\类型\大小(多少字 ...