Elasticsearch Scroll Api 示例

PHP 项目,通过 Elasticsearch 的 Scroll Api 循环获取所有搜索结果。因为老项目用的是 2.0+ 版本的旧版 Elasticsearch,使用的也是旧版的 PHP Client:"elasticsearch/elasticsearch": "^2.0"

为了调用 Scroll,先要做一次 Search,带 scroll 参数,表示搜索上下文的保存时间。Search 的结果会带 _scroll_id,之后循环调用 Scroll 去获取剩余的数据。比较反直觉的一点在于,每次去返回的结果里取的 _scroll_id 的值,可能是不变的。返回结果里 hits 为空,即没有新的数据时,Scroll 结束。我比较好奇如果其中一次 Scroll 没有获取成功,那是不是意味着数据就漏掉了?

示例代码

use Elasticsearch\ClientBuilder;

//...
$client = ClientBuilder::create()->setHosts($hosts)->build();
$hits = [];
$scroll = '1m';
$params = [
    'index' => $index,
    '_source' => ['id', 'content'],
    'body' => [
        'sort' => ['publish_time' => 'desc'],
        'size' => 10,
        'query' => $searchParams
    ],
    'scroll' => $scroll
];
$r = $client->search($params);
if(!empty($r['hits']['hits'])) {
    $hits = $r['hits']['hits'];
}
$scrollId = $r['_scroll_id'];
while ($scrollId) {
    $r = $client->scroll(
        [
            'scroll' => $scroll,
            'scroll_id' => $scrollId
        ]
    );
    if(!empty($r['hits']['hits'])) {
        $hits = array_merge($hits, $r['hits']['hits']);
    }
    if (!array_key_exists('_scroll_id', $r) || empty($r['hits']['hits'])) {
        $scrollId = false;
    }
}
var_dump($hits);

参考