def scan(client, query=None, scroll='5m', preserve_order=False, **kwargs):
    if not preserve_order:
        kwargs['search_type'] = 'scan'
    # initial search
    resp = client.search(body=query, scroll=scroll, **kwargs)

    scroll_id = resp.get('_scroll_id')
    if scroll_id is None:
        return

    first_run = True
    while True:
        # if we didn't set search_type to scan initial search contains data
        if preserve_order and first_run:
            first_run = False
        else:
            resp = client.scroll(scroll_id, scroll=scroll)
        if not resp['hits']['hits']:
            break
        for hit in resp['hits']['hits']:
            yield hit
        scroll_id = resp.get('_scroll_id')
        if scroll_id is None:
            break
Simple abstraction on top of the
dataset/ETHPy150Open hvandenb/splunk-elasticsearch/search-elasticsearch/bin/elasticsearch/helpers/__init__.py/scan