Docs Menu

Docs Homeアプリケーションの開発Python ドライバーPyMongo

カーソルからデータにアクセスする

項目一覧

  • 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) カーソル のガイド を参照してください。

PyMongo v 3.8またはそれ以前のバージョンでは、 Cursorコンストラクターに無効な引数を指定するとTypeErrorAttributeErrorが発生します。 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以降にアップグレードすることで、関連性のないエラーも排除されます。

MongoDB のカーソルは、サーバー上で操作が実行されずに長時間開いていると、サーバー上でタイムアウトすることがあります。 これにより、カーソルを反復処理しようとすると、 CursorNotFoundの例外が発生する可能性があります。

← 個別のフィールド値の取得