对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

从游标访问数据

在本指南中,您可以学习;了解如何使用MongoDB PHP库从游标访问权限数据。

游标是一种以可迭代批处理方式返回读取操作结果的机制。 游标在任何给定时间仅保存文档的子集,而不是一次返回所有文档,从而减少内存消耗和服务器请求数量。

每当MongoDB PHP库使用 MongoDB\Collection::find() 方法执行读取操作时,它都会在 MongoDB\Driver\Cursor实例中返回匹配的文档。Cursor 类实现了 PHP 的迭代器接口,该接口提供了对迭代的更多控制,并且与使用可迭代对象的PHP函数具有更高的兼容性。MongoDB游标仅支持前向迭代,因此您无法倒回游标或多次使用 foreach 循环。

The examples in this guide use the restaurants collection in the sample_restaurants database from the Atlas sample datasets. To access this collection from your PHP application, instantiate a MongoDB\Client that connects to an Atlas cluster and assign the following value to your $collection variable:

$collection = $client->sample_restaurants->restaurants;

要了解如何创建免费的 MongoDB 部署并加载示例数据集,请参阅 MongoDB入门指南。

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;
}

要从游标检索单个文档,请在MongoDB\Driver\Cursor实例上调用current()方法。 此方法返回游标最初指向的文档。 您可以通过调用next()方法继续使游标前进,该方法指示游标点下一个检索到的文档。

以下示例查找其中name字段值为'Dunkin' Donuts'的所有文档。 然后,它通过在游标上调用current()方法来打印检索到的第一个文档:

$cursor = $collection->find(['name' => 'Dunkin\' Donuts']);
$cursor->rewind();
echo json_encode($cursor->current());

警告

If the number and size of documents returned by your query exceeds available application memory, your program will crash. If you expect a large result set, access your cursor iteratively.

要从游标检索所有文档,请使用以下方法之一将游标转换为大量:

  • MongoDB\\Driver\\Cursor::toArray():调用MongoDB\Driver\Cursor对象

  • iterator_to_array():将MongoDB\Driver\Cursor对象作为参数传递

以下示例对游标调用toArray()方法,将其结果存储在大量中:

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

If you want a cursor to remain open after your client reads its initial contents, you can use a tailable cursor. We recommend that you use tailable cursors to query capped collections.

不能使用 foreach 循环来迭代可追加游标,因为循环在读取游标的初始结果设立后终止。如果使用第二个 foreach 循环继续迭代可追加游标,则PHP库会尝试倒带游标,然后生成错误。相反,您必须使用 Iterator 接口中的方法从可追加游标中检索结果。

要创建可追加游标,请在大量中将 cursorType 选项设立为 MongoDB\Operation\Find::TAILABLE。然后,将该大量作为选项参数传递给 MongoDB\Collection::find() 方法。

本部分提供以下示例脚本,您可以同时运行这些脚本:

  1. A producer script that creates a capped collection and inserts documents into it

  2. A consumer script that creates a tailable cursor to read documents from the capped collection

以下示例创建了一个名为 vegetables 的固定大小集合,并等待 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()]);

While the preceding code example is running, use the following code to create a tailable cursor and retrieve all documents in the vegetables collection:

$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();
}

此代码会打印集合中的两个初始文档,但 while 循环直到收到第三个文档后才会终止。next() 方法确保代码等待其他游标结果。

提示

To learn more about tailable cursors, see Tailable Cursors in the MongoDB Server manual.

要学习;了解有关读取操作的更多信息,请参阅《检索数据》指南。

要学习;了解有关游标的更多信息,请参阅扩展API文档中的以下页面:

要学习;了解有关find()方法的更多信息,请参阅MongoDB\Collection::find()的API文档。