文档菜单
文档首页
/ / /
PHP库手册
/

从游标访问数据

在本页

  • 概述
  • 迭代访问游标内容
  • 逐个检索文档
  • 检索所有文档
  • 可尾随游标
  • 附加信息

在本指南中,您可以了解如何使用 MongoDB PHP 库通过游标访问数据。

游标是一种机制,可以分批返回读取操作的结果。游标通过在任何给定时间只保留文档的子集,而不是一次性返回所有文档,从而减少了内存消耗和服务器请求数量。

当 MongoDB PHP 库通过以下方式执行读取操作时:MongoDB\Collection::find() 方法,它返回匹配的文档在 MongoDB\Driver\Cursor 实例中。

本指南中的示例使用来自 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']);
$array_results = $cursor->toArray();

当在有界集合上查询时,您可以使用在客户端耗尽游标结果后仍然保持打开的可续游标。要创建一个可续游标,在数组中将cursorType选项设置为MongoDB\Operation\Find::TAILABLE。然后,将数组作为选项参数传递给MongoDB\Collection::find()方法。

例如,您可以使用以下代码创建一个名为vegetables的有界集合,该集合存储表示蔬菜的文档

$db = $client->db;
$create_coll = $db->createCollection(
'vegetables',
['capped' => true, 'size' => 1024 * 1024]
);
$vegetables = [
['name' => 'cauliflower'],
['name' => 'zucchini']
];
$collection = $db->vegetables;
$result = $collection->insertMany($vegetables);

以下代码使用可续游标检索vegetables集合中的所有文档。在游标耗尽后,它将保持打开状态,直到检索到三个文档

$cursor = $collection->find([], ['cursorType' => MongoDB\Operation\Find::TAILABLE]);
$cursor->rewind();
$docs_found = 0;
while ($docs_found < 3) {
if ($cursor->valid()) {
$doc = $cursor->current();
echo json_encode($doc), PHP_EOL;
$docs_found++;
}
$cursor->next();
}
{"_id":{"$oid":"..."},"name":"cauliflower"}
{"_id":{"$oid":"..."},"name":"zucchini"}

如果您将另一个文档插入到vegetables集合中,前面的代码将打印新文档并关闭while循环。

有关可续游标的更多信息,请参阅MongoDB服务器手册中的可续游标

有关读取操作的更多信息,请参阅检索数据指南。

有关游标的更多信息,请参阅以下扩展API文档中的页面

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

返回

指定要返回的字段