网站首页 > 技术文章 正文
Elasticsearch调研深度查询
1.from/size 浅分页查询
一般的分页需求我们可以使用from和size的方式实现,但是这种的分页方式在深分页的场景下应该是避免使用的。深分页的页次增加,所消耗的内存和时间的增长也是成比例的增加,为了避免深度分页产生的问题,Elasticsearch从2.0版本楷书,增加了一个限制:
index.max_result_window = 10000
# elasticsearch的一种保护机制,限制1w条数据,但是可以修改最大限根据实际需求,不过最好不要修改会影响性能。
2.深分页 scroll
# 引入scroll
from/size查询查询在10000-50000条数据(1000到5000页)以内的时候还是可以的,但是如何数据量过多的话,就会出现深分页的问题
# 为了解决以上问题,elasticsearch提出了一个scroll滚动的方式。
scroll使用
1.scroll的原理是讲索引数据备份,每次记住最后一次查询的位置,下一次从最后一次位置开始查询。
2.使用scroll,通过size的查询最大限制,scroll返回一个代表最后一个size查询的位置scroll_id可以不断的获取下一页的内容。
1.第一次查询带scroll参数
GET tag-*/_search?scroll=10m
{
"query": {
"match_all": {}
},
"sort": [{"stime": {"order": "desc"}}],
"from": 0,
"size": 10000
}
1.scroll=5m表示设置scroll_id保留5分钟可用。
2.使用scroll必须要将from设置为0。
3.size决定后面每次调用_search搜索返回的数量
2.查询结果会返回scroll_id,第二次查询会带上scroll_id,就能从上一次查询的末尾开始查询了。
1.然后我们可以通过数据返回的_scroll_id读取下一页内容,每次请求将会读取下10000条数据,直到数据读取完毕或者scroll_id保留时间截止
2.请求的接口不再使用索引名了,而是 _search/scroll,其中GET和POST方法都可以使用。
GET /_search/scroll
{
"scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAC7EWa1U5THR6U0xSSXVOZjJTaUhpeHY2dw==",
"scroll": "10m"
}
3.scroll删除scroll在es的上下文中的数据
1.根据官方文档的说法,scroll的搜索上下文会在scroll的保留时间截止后自动清除,但是我们知道scroll是非常消耗资源的,所以一个建议就是当不需要了scroll数据的时候,尽可能快的把scroll_id显式删除掉,而且会生成历史快照,对于数据的变更不会反映到快照上。
DELETE /_search/scroll/DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAC7EWa1U5THR6U0xSSXVOZjJTaUhpeHY2dw==
4.scroll的使用场景(使用场景:数据导出)
1.可以看出scroll不适合支持那种实时的和用户交互的前端分页工作,其主要用途用于从ES集群分批拉取大量结果集的情况,一般都是offline的应用场景。 比如需要将非常大的结果集拉取出来,存放到其他系统处理,或者需要做大索引的reindex等等。
3.深分页search_after
建议使用Scroll api进行高效深度滚动,但滚动上下文代价很高,建议不要将其用于实时用户请求。该search_after参数通过提供实时游标来解决此问题。
search_after使用
1.search_after是ES5.0及之后版本提供的新特性,search_after有点类似scroll,但是和scroll又不一样,它提供一个活动的游标,通过上次查询的最后一条数据来进行下一次查询。
2.search_after分页的方式是根据上一页的最后一条数据来确定下一页的位置,同时在分页请求的过程中,如果有索引数据的增删改查,这些变更也会实时的反映到游标上。
3.但是需要注意,因为每一页的数据都是依赖于上一页最后一条数据,所以无法跳页请求。
1.search after 不能指定页数,只能一页挨一页问下查。第一次查询时带上sort,返回最后一个文档的id字段
1.每个文档具有一个唯一值的字段应该用作排序规范的仲裁器。否则,具有相同排序值的文档的排序顺序将是未定义的。建议的方法是使用字段_id,它肯定包含每个文档的一个唯一值。
2.为了找到每一页最后一条数据,每个文档必须有一个全局唯一值,官方推荐使用 _uid 作为全局唯一值,其实使用业务层的 id 也可以。
GET tag-*/_search
{
"query": {
"match_all": {}
},
"sort": [
{"stime": {"order": "desc"}},
{"_id": {"order": "desc"}}
],
"from": 0,
"size": 10000
}
# 为了根据最后一条数据的唯一标识来查询1w后面的数据
1.可以使用id的唯一标识,或者id加stime时间,来查询1w的后面数据。
2.当前我们search_after使用的唯一标识有id和stime,那么sort排序就必须加入stime和id排序不然会报错。
2.下一次查询带上search after参数
1.上面的请求会为每一个文档返回一个包含sort排序值的数组。这些sort排序值可以被用于 search_after 参数里以便抓取下一页的数据。比如,我们可以使用最后的一个文档的sort排序值,将它传递给 search_after 参数:
GET tag-*/_search
{
"query": {
"match_all": {}
},
"sort": [
{"stime": {"order": "desc"}},
{"_id": {"order": "desc"}}
],
"search_after": ["2022-09-25T12:38:42.142Z", "pxOodIMBf53JeIypLfhE"],
"from": 0,
"size": 10000
}
使用search_after必须要设置from=0。
这里我使用timestamp和_id作为唯一值排序。
我们在返回的最后一条数据里拿到sort属性的值传入到search_after。
3.删除和特性
1.search_after不是自由跳转到随机页面而是并行滚动多个查询的解决方案。它与滚动API非常相似,但与它不同,search_after参数是无状态的,它始终针对最新版本的搜索器进行解析。因此,排序顺序可能会在步行期间发生变化,具体取决于索引的更新和删除。
4.search_after应用场景
1.不支持跳页查询
# 另外在ES6.5的文档中有这样一句话需要注意一下:
2.另外,search_after并不是随机的查询某一页数据,而是并行的滚屏查询;search_after的查询顺序会在更新和删除时发生变化,也就是说支持实时的数据查询
3.大致的意思就是,如果search_after中的关键字为654,那么654323的文档也会被搜索到,所以在选择search_after的排序字段时需要谨慎,可以使用比如文档的id或者时间戳等
- 上一篇: 如何写一个简单的分页
- 下一篇: 千万级大表分页查询效率剧降,你会怎么办?
猜你喜欢
- 2025-05-11 FANUC修改前端目录教程
- 2025-05-11 前端分享-Set你不知道的事
- 2025-05-11 jq+ajax+bootstrap改了一个动态分页的表格
- 2025-05-11 千万级大表分页查询效率剧降,你会怎么办?
- 2025-05-11 如何写一个简单的分页
- 2025-05-11 手速太快引发分页翻车?前端竞态陷阱揭秘
- 2024-09-21 浅谈MySQL分页查询的工作原理
- 2024-09-21 使用Vue创建一个分页组件
- 2024-09-21 GO语言札记-分页技术实现
- 2024-09-21 SSM 框架!实现分页和搜索分页
你 发表评论:
欢迎- 05-11FANUC修改前端目录教程
- 05-11前端分享-Set你不知道的事
- 05-11jq+ajax+bootstrap改了一个动态分页的表格
- 05-11千万级大表分页查询效率剧降,你会怎么办?
- 05-11Elasticsearch深度分页
- 05-11如何写一个简单的分页
- 05-11手速太快引发分页翻车?前端竞态陷阱揭秘
- 05-11「linux」Socket缓存是如何影响TCP性能的?
- 最近发表
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端md5加密 (49)
- 前端路由 (55)
- 前端数组 (65)
- 前端定时器 (47)
- 前端懒加载 (45)
- 前端接口 (46)
- Oracle RAC (73)
- oracle恢复 (76)
- oracle 删除表 (48)
- oracle 用户名 (74)
- oracle 工具 (55)
- oracle 内存 (50)
- oracle 导出表 (57)
- oracle约束 (46)
- oracle 中文 (51)
- oracle链接 (47)
- oracle的函数 (57)
- mac oracle (47)
- 前端调试 (52)
- 前端登录页面 (48)
本文暂时没有评论,来添加一个吧(●'◡'●)