📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

使用滚动上下文从单个搜索请求中检索大量结果,保持搜索一致性视图。

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布尔值falsehits.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": []
  }
}

滚动参数说明 #

参数格式示例描述
scroll1m10m1h滚动上下文保持时间
scroll_id64 字符编码字符串滚动上下文的唯一标识符

滚动时间设置 #

时间适用场景
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 [...]"
  }
}

需要重新执行初始搜索。

注意事项 #

  1. 内存消耗:每个滚动上下文占用服务器内存
  2. 实时性:滚动期间的数据变化不会反映到结果中
  3. 过期时间:超过 scroll 时间未使用会自动清除
  4. URL 参数:7.x 版本后不推荐通过 URL 传递 scroll_id
  5. 清除:完成后务必清除滚动上下文

性能考虑 #

操作性能影响
长时间滚动持续占用内存
大批量大小单次请求时间增加
多并发滚动内存消耗大
超时时间内存释放延迟