1. From + size 查询优缺点及适用场景
From + size 查询优点
- 支持随机翻页。
From + size 查询缺点
- 受制于 max_result_window 设置,不能无限制翻页。
- 存在深度翻页问题,越往后翻页越慢。
From + size 查询适用场景
第一:非常适合小型数据集或者大数据集返回 Top N(N <= 10000)结果集的业务场景。
第二:类似主流 PC 搜索引擎(谷歌、bing、百度、360、sogou等)支持随机跳转分页的业务场景。
语句
GET /xxxx/_search
{
"sort": [
{
"id.keyword": {
"order": "asc"
}
}
],
"_source": ["id","name"],
"from": 0, ---从0开始. 不是1
"size": 5
}
第二页
GET /xxxx/_search
{
"sort": [
{
"id.keyword": {
"order": "asc"
}
}
],
"_source": ["id","name"],
"from": 5, ---第二页 0+5=5, 第三页5+5=10
"size": 5
}
from:未指定,默认值是 0,注意不是1,代表当前页返回数据的起始值。
size:未指定,默认值是 10,代表当前页返回数据的条数。
默认的深度分页限制是1万,from + size 大于 10000会报错,如何处理
默认的深度分页限制是1万,from + size 大于 10000会报错,可以通过index.max_result_window
参数进行修改。
在索引中增加配置
PUT mr_zcy/_settings
{
"index":{
"max_result_window":200000
}
}
from=10000 就不报错了
GET /mr_zcy/_search
{
"sort": [
],
"from": 10000,
"size": 2
}
2. search_after 查询优缺点及适用场景
使用search_after
必须要设置from=0
。
search_after 优点
- 不严格受制于 max_result_window,可以无限制往后翻页。
ps:不严格含义:单次请求值不能超过 max_result_window;但总翻页结果集可以超过。
search_after 缺点
- 只支持向后翻页,不支持随机翻页。
search_after 适用场景
- 类似:今日头条分页搜索
不支持随机翻页,更适合手机端应用的场景。
语句
第一页
GET /mr_zcy/_search
{
"sort": [
{
"id.keyword": {
"order": "desc"
}
}
],
"_source": [
"id",
"updateTime"
],
"size": 6
}
第二页
GET /mr_zcy/_search
{
"sort": [
{
"id.keyword": {
"order": "desc"
}
}
],
"_source": [
"id",
"updateTime"
],
"size": 6,
"search_after": [
745,
"2022-07-28 14:18:46"
]
}
--
search_after 中是 第一次查询结果里面
"sort" : [
745,
"2022-07-28 14:18:46"
]
在返回的结果中,最后一个文档有类似下面的数据,由于我们排序用的是两个字段,返回的是两个值
"sort" : [
1614561419000,
"6FxZJXgBE6QbUWetnarH"
]
Scroll 遍历查询优缺点及适用场景
from+size查询在10000-50000条数据(1000到5000页)以内的时候还是可以的,但是如果数据过多的话,就会出现深分页问题。
为了解决上面的问题,elasticsearch提出了一个scroll滚动的方式。
scroll 类似于sql中的cursor,使用scroll,每次只能获取一页的内容,然后会返回一个scroll_id
。根据返回的这个scroll_id
可以不断地获取下一页的内容,所以scroll并不适用于有跳页的情景。
scroll 查询优点
- 支持全量遍历。
ps:单次遍历的 size 值也不能超过 max_result_window 大小。
scroll 查询缺点
- 响应时间非实时。
- 保留上下文需要足够的堆内存空间。
scroll 查询适用场景
- 全量或数据量很大时遍历结果数据,而非分页查询。
- 官方文档强调:不再建议使用scroll API进行深度分页。如果要分页检索超过 Top 10,000+ 结果时,推荐使用:PIT + search_after。
- 数据导出功能
从 Scroll 请求返回的结果反映了发出初始搜索请求时索引的状态,类似在那一个时刻做了快照。随后对文档的更改(写入、更新或删除)只会影响以后的搜索请求。
第一次
GET project_base_info/_search?scroll=4m
{
"query": {
....
},
"sort": [
{
"alarmNum": {
"order": "asc",
"missing": 0
}
},
{
"priority_code":{
"order": "asc"
}
},{
"id.keyword":{
"order": "desc"
}
}
],
"size":100
}
执行结果有
"_scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAABlXwoWbVFramtrLTNTTU9IUHBSM3d6bGtSZw==",
后续执行, 循环执行,直到没有数据返回表示已经全部数据了
POST _search/scroll
{
"scroll" : "1m",
"scroll_id" :"DXF1ZXJ5QW5kRmV0Y2gBAAAAAABlXwoWbVFramtrLTNTTU9IUHBSM3d6bGtSZw=="
}
上面的scroll指定搜索上下文保留的时间,1m代表1分钟,还有其他时间可以选择,有d、h、m、s等,分别代表天、时、分钟、秒。
搜索上下文有过期自动删除,但如果自己知道什么时候该删,可以自己手动删除,减少资源占用
DELETE /_search/scroll
{
"scroll_id" : "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAA6UWWVJRTk9TUXFTLUdnU28xVFN6bEM4QQ=="
}
-
scroll=5m
表示设置scroll_id
保留5分钟可用。 - 使用scroll必须要将from设置为0。
- size决定后面每次调用
_search
搜索返回的数量
然后我们可以通过数据返回的_scroll_id
读取下一页内容,每次请求将会读取下10条数据,直到数据读取完毕或者scroll_id
保留时间截止:
根据官方文档的说法,scroll的搜索上下文会在scroll的保留时间截止后自动清除,但是我们知道scroll是非常消耗资源的,所以一个建议就是当不需要了scroll数据的时候,尽可能快的把scroll_id
显式删除掉。
清除所有的scroll:
DELETE _search/scroll/_all