Overview
このガイドでは、 MongoDB PHPライブラリを使用して、カーソルからデータにアクセスする方法を学習できます。
カーソルは、読み取り操作の結果を反復可能なバッチで返すメカニズムです。 カーソルは、すべてのドキュメントを一度に返すのではなく、常にドキュメントのサブセットのみを保持することで、メモリ消費とサーバーリクエスト数の両方を削減します。
MongoDB PHPライブラリが MongoDB\Collection::find() メソッドを使用して読み取り操作を実行するたびに、MongoDB\Driver\Cursorインスタンスに一致するドキュメントが返されます。The CursorクラスはPHP の イテレータ インターフェースを実装します。これにより、反復処理がより詳細になり、イテラブルを処理するPHP関数との互換性が向上します。MongoDBカーソルはフォワード反復のみをサポートしているため、カーソルをロールバックしたり、foreach ループを複数回使用したりすることはできません。
サンプル データ
このガイドの例では、 Atlasサンプルデータセットのsample_restaurantsデータベースのrestaurantsコレクションを使用します。 PHPアプリケーションからこのコレクションにアクセスするには、Atlas クラスターに接続するMongoDB\Clientをインスタンス化し、次の値を$collection変数に割り当てます。
$collection = $client->sample_restaurants->restaurants;
MongoDB Atlasクラスターを無料で作成して、サンプルデータセットをロードする方法については、 「Atlas を使い始める」ガイドを参照してください。
カーソルの内容に反復的にアクセスする
MongoDB\Driver\CursorクラスはIteratorインターフェースを実装しているため、 foreachループを使用してその内容を反復処理できます。
次の例では、 MongoDB\Collection::find()メソッドを使用して、 nameフィールドの値が'Dunkin' Donuts'であるすべてのドキュメントを取得します。 次に、 find()メソッドによって返されたカーソルから各ドキュメントを出力します。
$cursor = $collection->find(['name' => 'Dunkin\' Donuts']); foreach ($cursor as $doc) { echo json_encode($doc), PHP_EOL; }
{"_id":{"$oid":"..."},..."name":"Dunkin' Donuts","restaurant_id":"40379573"} {"_id":{"$oid":"..."},..."name":"Dunkin' Donuts","restaurant_id":"40363098"} {"_id":{"$oid":"..."},..."name":"Dunkin' Donuts","restaurant_id":"40395071"} ...
ドキュメントを個別に検索する
カーソルから個々のドキュメントを検索するには、 MongoDB\Driver\Cursorインスタンスでcurrent()メソッドを呼び出します。 このメソッドは、カーソルが最初に指したドキュメントを返します。 next()メソッドを呼び出すことで、カーソルを続行できます。このメソッドは、次に検索されたドキュメントを点ようにカーソルに指示します。
次の例では、 nameの フィールド値が'Dunkin' Donuts'であるすべてのドキュメントを検索します。 次に、カーソルでcurrent()メソッドを呼び出して、最初に検索されたドキュメントを出力します。
$cursor = $collection->find(['name' => 'Dunkin\' Donuts']); $cursor->rewind(); echo json_encode($cursor->current());
{"_id":{"$oid":"..."},..."name":"Dunkin' Donuts","restaurant_id":"40379573"}
すべてのドキュメントを検索する
警告
クエリによって返されたドキュメントの数とサイズが利用可能なアプリケーション メモリを超えると、プログラムはクラッシュします。 大規模な結果セットが予想される場合は、カーソルに反復的にアクセスしてください。
カーソルからすべてのドキュメントを検索するには、次のいずれかの方法を使用してカーソルを配列に変換します。
MongoDB$Driver\Cursor::toArray() :
MongoDB\Driver\Cursorオブジェクトで を呼び出すイテレータ_to_array() :
MongoDB\Driver\Cursorオブジェクトをパラメータとして渡す
次の例では、カーソルでtoArray()メソッドを呼び出し、その結果を配列に保存します。
$cursor = $collection->find(['name' => 'Dunkin\' Donuts']); $resultArray = $cursor->toArray();
テール可能カーソル
クライアントが初期内容を読み込んだ後もカーソルを開いたままにしたい場合は、追尾可能 (tailable) カーソルを使用できます。Cappedコレクションをクエリするには、 追尾可能 (tailable) カーソル を使用することをお勧めします。
追尾可能 (tailable) カーソル を反復処理するために foreach ループは使用できません。このループはカーソルの初期結果セットを読み込んだ後に終了するためです。2 つ目の foreach ループを使用して追尾可能 (tailable) カーソル の反復処理を続けると、 PHPライブラリはカーソルを巻き戻すことを試み、エラーを生成します。代わりに、追尾可能 (tailable) カーソルから結果を検索するには、 イテレータ インターフェースのメソッドを使用する必要があります。
追尾可能 (tailable) カーソルを作成するには、cursorType オプションを配列で MongoDB\Operation\Find::TAILABLE に設定します。次に、その配列をオプション パラメーターとして MongoDB\Collection::find() メソッドに渡します。
追尾可能 (tailable) カーソルの例
このセクションでは、同時に実行できる次のサンプルスクリプトを紹介します。
Cappedコレクションからドキュメントを読み取るための追尾可能 (tailable) カーソルを作成するコンシューマースクリプト
コレクションの作成と入力
次の例では、vegetables というCappedコレクションを作成し、 5 秒間待ってからコレクションに追加のドキュメントを挿入します。
$db = $client->db; $db->createCollection( 'vegetables', ['capped' => true, 'size' => 1024 * 1024], ); $vegetables = [ ['name' => 'cauliflower', 'createdAt' => new MongoDB\BSON\UTCDateTime()], ['name' => 'zucchini', 'createdAt' => new MongoDB\BSON\UTCDateTime()], ]; $collection = $db->vegetables; $result = $collection->insertMany($vegetables); sleep(5); $collection->insertOne(['name' => 'carrot', 'createdAt' => new MongoDB\BSON\UTCDateTime()]);
追尾可能 (tailable) カーソルの作成
上記のコード例では が実行中が、次のコードを使用して追尾可能 (tailable) カーソルを作成し、vegetablesコレクション内のすべてのドキュメントを検索します。
$cursor = $collection->find([], ['cursorType' => MongoDB\Operation\Find::TAILABLE]); $cursor->rewind(); $docsFound = 0; while ($docsFound < 3) { if ($cursor->valid()) { $doc = $cursor->current(); echo json_encode($doc), PHP_EOL; $docsFound++; } $cursor->next(); }
{"_id":{"$oid":"..."},"name":"cauliflower","createdAt":{"$date":{"$numberLong":"..."}}} {"_id":{"$oid":"..."},"name":"zucchini","createdAt":{"$date":{"$numberLong":"..."}}} {"_id":{"$oid":"..."},"name":"carrot","createdAt":{"$date":{"$numberLong":"..."}}}
このコードはコレクション内の 2 つの最初のドキュメントを出力しますが、while ループは 3 つ目のドキュメントを受信するまで終了しません。next() メソッドを使用すると、コードが追加のカーソル結果を待機するようになります。
Tip
追尾可能 (tailable) カーソルの詳細については、 MongoDB Serverマニュアルの「追尾可能(tailable) カーソル 」を参照してください。
詳細情報
読み取り操作の詳細については、 データの取得ガイドを 参照してください。
カーソルの詳細については、 拡張APIドキュメントの次のページを参照してください。
API ドキュメント
find()メソッドの詳細については、 MongoDB\Collection::find()のAPIドキュメントを参照してください。