Join us Sept 17 at .local NYC! Use code WEB50 to save 50% on tickets. Learn more >
MongoDB Event
Docs Menu
Docs Home
/ / /
PHP ライブラリ マニュアル
/ /

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

このガイドでは、 MongoDB PHPライブラリを使用して、カーソルからデータにアクセスする方法を学習できます。

カーソルは、読み取り操作の結果を反復可能なバッチで返すメカニズムです。 カーソルは、すべてのドキュメントを一度に返すのではなく、常にドキュメントのサブセットのみを保持することで、メモリ消費とサーバーリクエスト数の両方を削減します。

MongoDB PHPライブラリがMongoDB\Collection::find() メソッドを使用して読み取り操作を実行するたびに、MongoDB\Driver\Cursor インスタンスに一致するドキュメントが返されます。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オブジェクトで を呼び出す

  • iterator_to_array(): MongoDB\Driver\Cursorオブジェクトをパラメーターとして渡す

次の例では、カーソルでtoArray()メソッドを呼び出し、その結果を配列に保存します。

$cursor = $collection->find(['name' => 'Dunkin\' Donuts']);
$resultArray = $cursor->toArray();

クライアントが初期内容を読み込んだ後もカーソルを開いたままにしたい場合は、追尾可能 (tailable) カーソルを使用できます。Cappedコレクションをクエリするには、 追尾可能 (tailable) カーソル を使用することをお勧めします。

foreach追尾可能 (tailable) カーソル を反復処理するために ループは使用できません。このループはカーソルの初期結果セットを読み込んだ後に終了するためです。 2 つ目のforeach ループを使用して追尾可能 (tailable) カーソル の反復処理を続けると、 PHPライブラリはカーソルを巻き戻すことを試み、エラーを生成します。代わりに、追尾可能 (tailable) カーソルから結果を検索するには、 イテレータ インターフェースのメソッドを使用する必要があります。

追尾可能 (tailable) カーソルを作成するには、cursorType オプションを配列で MongoDB\Operation\Find::TAILABLE に設定します。次に、その配列をオプション パラメーターとして MongoDB\Collection::find() メソッドに渡します。

このセクションでは、同時に実行できる次のサンプルスクリプトを紹介します。

  1. Cappedコレクションを作成し、そのコレクションにドキュメントを挿入するプロデューサー用スクリプト

  2. 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) カーソルを作成し、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ドキュメントの次のページを参照してください。

find()メソッドの詳細については、 MongoDB\Collection::find()のAPIドキュメントを参照してください。

戻る

個別のフィールド値

項目一覧