使用滚动上下文从单个搜索请求中检索大量结果,保持搜索一致性视图。
API #
获取滚动结果 #
GET /_search/scroll
POST /_search/scroll
GET /_search/scroll/{scroll_id}
POST /_search/scroll/{scroll_id}
清除滚动上下文 #
DELETE /_search/scroll
DELETE /_search/scroll/{scroll_id}
DELETE /_search/scroll/_all
API 的作用 #
滚动搜索允许从单个搜索请求中检索大量结果(如 10,000+ 条)。
滚动搜索的特点 #
| 特点 | 描述 |
|---|---|
| 快照视图:保持搜索时的一致性视图 | |
| 长时间保持:可设置保持时间(如 1 分钟) | |
| 内存消耗:每个滚动上下文占用内存 | |
| 适用场景:数据导出、批处理、数据迁移 |
滚动 vs search_after #
| 方式 | 优点 | 缺点 |
|---|---|---|
| Scroll | 搜索一致性视图 | 占用内存 |
| search_after | 不占用内存,支持实时数据 | 需要排序字段 |
API 的参数 #
GET/POST /_search/scroll #
Query String 参数 #
| 参数 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
scroll | 时间值 | 否 | 初始搜索的时间 | 滚动上下文保持时间 |
scroll_id | 字符串 | 否* | - | 滚动 ID(推荐在请求体中传递) |
rest_total_hits_as_int | 布尔值 | 否 | false | hits.total 是否呈现为整数 |
请求体参数 #
{
"scroll": "1m",
"scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAA..."
}
或数组格式:
{
"scroll": "1m",
"scroll_id": ["id1", "id2", "id3"]
}
DELETE /_search/scroll #
Query String 参数 #
| 参数 | 类型 | 是否必填 | 描述 |
|---|---|---|---|
{scroll_id} | 字符串 | 否* | 要清除的滚动 ID |
请求体参数 #
{
"scroll_id": ["id1", "id2", "id3"]
}
示例 #
初始滚动搜索 #
GET /my_index/_search?scroll=1m
{
"size": 100,
"query": {
"match_all": {}
}
}
响应示例:
{
"_scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAA...",
"took": 10,
"timed_out": false,
"_shards": { ... },
"hits": {
"total": {
"value": 1000,
"relation": "eq"
},
"hits": [ ... ]
}
}
获取下一批结果 #
POST /_search/scroll
{
"scroll": "1m",
"scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAA..."
}
获取多批结果 #
# 第一批
GET /my_index/_search?scroll=1m
{
"size": 100,
"query": { "match_all": {} }
}
# 第二批
POST /_search/scroll
{
"scroll": "1m",
"scroll_id": "从第一批响应中获取的 _scroll_id"
}
# 第三批
POST /_search/scroll
{
"scroll": "1m",
"scroll_id": "从第二批响应中获取的 _scroll_id"
}
清除单个滚动上下文 #
DELETE /_search/scroll/DXF1ZXJ5QW5kRmV0Y2gBAAAA...
清除所有滚动上下文 #
DELETE /_search/scroll/_all
清除多个滚动上下文 #
DELETE /_search/scroll
{
"scroll_id": ["id1", "id2", "id3"]
}
处理空结果 #
当没有更多结果时:
{
"_scroll_id": "DXF1ZXJ5QW5kRmV0Y2gBAAAA...",
"took": 5,
"timed_out": false,
"_shards": { ... },
"hits": {
"total": {
"value": 1000,
"relation": "eq"
},
"hits": []
}
}
滚动参数说明 #
| 参数 | 格式示例 | 描述 |
|---|---|---|
scroll | 1m、10m、1h | 滚动上下文保持时间 |
scroll_id | 64 字符编码字符串 | 滚动上下文的唯一标识符 |
滚动时间设置 #
| 时间 | 适用场景 |
|---|---|
1m | 默认推荐,适合大多数场景 |
5m | 较大的数据导出 |
10m | 大数据量处理 |
1h | 非常大的数据集(不推荐) |
使用场景 #
场景 1:数据导出 #
# 初始搜索
GET /logs/_search?scroll=2m
{
"size": 1000,
"query": {
"range": {
"@timestamp": {
"gte": "2026-01-01",
"lt": "2026-02-01"
}
}
}
}
# 持续获取下一批
POST /_search/scroll
{
"scroll": "2m",
"scroll_id": "..."
}
# 完成后清除
DELETE /_search/scroll/...
场景 2:数据重新索引 #
GET /source_index/_search?scroll=5m
{
"size": 500,
"_source": ["field1", "field2", "field3"]
}
场景 3:机器学习批处理 #
GET /training_data/_search?scroll=10m
{
"size": 1000,
"query": {
"match": { "category": "training" }
}
}
响应字段说明 #
滚动结果响应 #
| 字段 | 描述 |
|---|---|
_scroll_id | 下一次滚动使用的 ID |
took | 执行时间(毫秒) |
timed_out | 是否超时 |
_shards | 分片信息 |
hits.total | 总命中数 |
hits.hits | 文档数组 |
滚动完成指示 #
当 hits.hits 为空数组时,表示已获取所有结果。
最佳实践 #
1. 及时清除上下文 #
# 完成后立即清除
DELETE /_search/scroll/scroll_id
2. 使用合理的滚动时间 #
# 根据数据量设置
小数据集: scroll=1m
大数据集: scroll=5m
3. 批量大小 #
{
"size": 1000 # 推荐 500-1000
}
4. 错误处理 #
当滚动上下文过期时:
{
"error": {
"type": "search_context_missing_exception",
"reason": "No search context found for id [...]"
}
}
需要重新执行初始搜索。
注意事项 #
- 内存消耗:每个滚动上下文占用服务器内存
- 实时性:滚动期间的数据变化不会反映到结果中
- 过期时间:超过 scroll 时间未使用会自动清除
- URL 参数:7.x 版本后不推荐通过 URL 传递 scroll_id
- 清除:完成后务必清除滚动上下文
性能考虑 #
| 操作 | 性能影响 |
|---|---|
| 长时间滚动 | 持续占用内存 |
| 大批量大小 | 单次请求时间增加 |
| 多并发滚动 | 内存消耗大 |
| 超时时间 | 内存释放延迟 |





