カーソルからデータにアクセスする
Overview
このガイドでは、PyMongo を使用してカーソルからデータにアクセスする方法を学習できます。
カーソルは、読み取り操作の結果を反復可能なバッチで返すメカニズムです。 カーソルは一度にドキュメントのサブセットのみを保持するため、メモリ消費とネットワーク帯域幅使用量の両方が削減されます。
PyMongo が複数のドキュメントを返す読み取り操作を実行するたびに、それらのドキュメントをカーソルで自動的に返します。
サンプル データ
このガイドの例では、 Atlas サンプル データセットの sample_restaurants.restaurants
コレクションを使用します。 無料の MongoDB Atlas クラスターを作成し、サンプル データセットをロードする方法については、 PyMongo を使い始める を参照してください。
カーソルの内容に反復的にアクセスする
カーソルの内容を反復処理するには、次の例に示すようにfor
ループを使用します。
results = collection.find() for document in results: print(document)
ドキュメントを個別に検索する
カーソルからドキュメントを個別に取得するには、 next()
メソッドを呼び出します。
次の例では、 name
の値が"Dunkin' Donuts"
である コレクション内のすべてのドキュメントを検索します。 次に、 next()
メソッドを呼び出してカーソルの最初のドキュメントを出力します。
results = collection.find({ "name": "Dunkin' Donuts" }) print(results.next())
{'_id': ObjectId('...'), 'address': { ... }, 'borough': 'Bronx', 'cuisine': 'Donuts', 'grades': [...], 'name': "Dunkin' Donuts", 'restaurant_id': '40379573'}
すべてのドキュメントを検索する
警告
クエリによって返されたドキュメントの数とサイズが利用可能なアプリケーション メモリを超えると、プログラムはクラッシュします。 大規模な結果セットが予想される場合は、カーソルに反復的にアクセスしてください。
カーソルからすべてのドキュメントを検索するには、次の例に示すように、カーソルをlist
に変換します。
results = collection.find({ "name": "Dunkin' Donuts" }) all_results = list(results) for document in all_results: print(document)
カーソルを閉じる
デフォルトでは、クライアントがカーソル内の結果をすべて使い切ると、MongoDB はカーソルを閉じます。 カーソルを明示的に閉じるには、次の例に示すようにclose()
メソッドを呼び出します。
results = collection.find() ... results.close()
テール可能カーソル
Cappedコレクションをクエリする場合、クライアントがカーソルの結果を使い果たした後も開いたままになる 追尾可能 ( tailable) カーソルを使用できます。 Cappedコレクションを使用して追尾可能 (tailable) カーソルを作成するには、 find()
メソッドのcursor_type
オプションでCursorType.TAILABLE_AWAIT
を指定します。
次の例では、 追尾可能 (tailable) カーソル を使用して、レプリカセット ノードの oplog を追跡します。
oplog = client.local.oplog.rs first = oplog.find().sort('$natural', pymongo.ASCENDING).limit(-1).next() print(first) ts = first['ts'] while True: cursor = oplog.find({'ts': {'$gt': ts}}, cursor_type=pymongo.CursorType.TAILABLE_AWAIT) while cursor.alive: for doc in cursor: ts = doc['ts'] print(doc) # You end up here if the find() method returns no documents, or if # no new documents are added to the collection for more than 1 second. time.sleep(1)
追尾可能 (tailable) カーソルの詳細については、MongoDB Server マニュアルの 追尾可能 ( tailable) カーソル のガイド を参照してください。
トラブルシューティング
「カーソル」オブジェクトには属性「_Cursor_killed」がありません
PyMongo v 3.8またはそれ以前のバージョンでは、 Cursor
コンストラクターに無効な引数を指定するとTypeError
とAttributeError
が発生します。 AttributeError
は関係ありませんが、 TypeError
には次の例に示すようにデバッグ情報が含まれています。
Exception ignored in: <function Cursor.__del__ at 0x1048129d8> ... AttributeError: 'Cursor' object has no attribute '_Cursor__killed' ... TypeError: __init__() got an unexpected keyword argument '<argument>'
これを修正するには、適切なキーワード引数を指定していることを確認してください。 また、PyMongo v 3.9以降にアップグレードすることで、関連性のないエラーも排除されます。
" CursorNotFound カーソル ID はサーバーで無効です "
MongoDB のカーソルは、サーバー上で操作が実行されずに長時間開いていると、サーバー上でタイムアウトすることがあります。 これにより、カーソルを反復処理しようとすると、 CursorNotFound
の例外が発生する可能性があります。