ELK新手求助:如何在Elasticsearch中获取超10000条文档?
为什么默认无法获取超过10000条?
Elasticsearch默认限制from + size的最大值为10000(由index.max_result_window参数控制),这是为了避免深度分页带来的内存和性能损耗。直接调大这个参数不推荐,会显著影响集群稳定性。
方法一:使用Scroll API(适合一次性批量导出)
Scroll API是专门为批量获取大量数据设计的,它会创建一个数据快照,后续请求基于这个快照获取数据,无需依赖上一批结果的排序值,完全适配你的需求。
步骤1:初始化Scroll
发送初始请求,指定scroll参数设置快照保留时长(比如1m表示1分钟),同时设置每页返回的文档数量(size):
GET twitter/_search?scroll=1m { "query": { "match": { "title": "elasticsearch" } }, "size": 1000, "sort": [ {"date": "asc"}, {"tie_breaker_id": "asc"} ] }
响应结果中会返回_scroll_id,后续请求需要用这个ID来获取下一页数据。
步骤2:循环获取后续数据
每次请求使用上一次返回的_scroll_id,直到返回的hits.hits为空,说明所有数据已获取完成:
GET _search/scroll { "scroll": "1m", "scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ==" }
注意事项
- 快照保留时长要足够完成所有数据获取,但也不要设置过长,避免占用过多集群资源。
- 数据全部获取完成后,记得手动清理scroll上下文,释放资源:
DELETE _search/scroll { "scroll_id": ["DXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAD4WYm9laVYtZndUQlNsdDcwakFMNjU1QQ=="] }
方法二:使用Point in Time(PIT)结合Search After(高效持续分页)
如果需要持续获取数据(比如后续可能有新数据写入),PIT会比Scroll更高效。它创建一个时间点快照,后续通过search_after基于这个快照分页,你可以自动提取上一次结果的排序值,无需手动记录。
步骤1:创建PIT
POST twitter/_pit?keep_alive=1m
响应中会返回id(即PIT ID)。
步骤2:初始查询获取数据
GET _search { "size": 1000, "query": { "match": { "title": "elasticsearch" } }, "sort": [ {"date": "asc"}, {"tie_breaker_id": "asc"} ], "pit": { "id": "46ToAwMDaWR5BXV1aWQyKwZub2RlXzMAAAAAAAAAACoBYwADaWR4BXV1aWQxAgZub2RlXzEAAAAAAAAAAAEBYQADaWR5BXV1aWQyKgZub2RlXzIAAAAAAAAAAAwBYgACBXV1aWQyAAAFdXVpZDEAAQltYXRjaF9hbGw_gAAAAA==", "keep_alive": "1m" } }
从响应的hits.hits最后一条数据的sort字段,提取下一次请求需要的search_after值。
步骤3:循环获取后续数据
每次请求传入上一次的search_after值和PIT ID:
GET _search { "size": 1000, "query": { "match": { "title": "elasticsearch" } }, "search_after": [1463538857, "654323"], "sort": [ {"date": "asc"}, {"tie_breaker_id": "asc"} ], "pit": { "id": "46ToAwMDaWR5BXV1aWQyKwZub2RlXzMAAAAAAAAAACoBYwADaWR4BXV1aWQxAgZub2RlXzEAAAAAAAAAAAEBYQADaWR5BXV1aWQyKgZub2RlXzIAAAAAAAAAAAwBYgACBXV1aWQyAAAFdXVpZDEAAQltYXRjaF9hbGw_gAAAAA==", "keep_alive": "1m" } }
直到hits.hits为空,结束循环。
步骤4:清理PIT
数据获取完成后,删除PIT释放资源:
DELETE _pit { "id": "46ToAwMDaWR5BXV1aWQyKwZub2RlXzMAAAAAAAAAACoBYwADaWR4BXV1aWQxAgZub2RlXzEAAAAAAAAAAAEBYQADaWR5BXV1aWQyKgZub2RlXzIAAAAAAAAAAAwBYgACBXV1aWQyAAAFdXVpZDEAAQltYXRjaF9hbGw_gAAAAA==" }
总结
如果是一次性导出大量数据,Scroll API是最适合你的选择,操作简单且无需依赖上一批结果的排序值;如果需要长期持续分页获取数据,推荐使用PIT + Search After,性能更优。
内容的提问来源于stack exchange,提问作者Lucian

