Python yield反復アクセスmongo


mongoではlimit()メソッドを使用して指定数のデータを読み出し、skip()メソッドを使用して指定数のデータをスキップします.しかしskipは1本1本が遍歴しており、データ量が大きい場合、skipの性能は憂慮されている.遅い根本的な原因は、「インデックスに依存するb+構造がランキング計算に使用できない」ことです.テーブル全体を巡回してデータを取得する必要があるシーンでは、_を一時保存できます.idは,yield方式でmongo集合にアクセスし,skipの使用を回避する.
#       mongo
def find_iter(collcetion, limit=100, spec={}):
    min_id = list(collcetion.find(spec).sort('_id', 1).limit(1))[0]['_id']
    max_id = list(collcetion.find(spec).sort('_id', -1).limit(1))[0]['_id']

    # return first row
    curr_id = min_id
    spec.update({'_id': {'$gte': curr_id}})
    _row = collcetion.find_one(spec)
    yield _row

    if curr_id == max_id:
        raise StopIteration

    # return left data
    while True:
        spec.update({'_id': {'$gt': curr_id}})
        for _row in collcetion.find(spec).sort('_id').limit(limit):
            curr_id = _row['_id']
            yield _row

            if curr_id == max_id:
                raise StopIteration