Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions snooty.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ php-library = "MongoDB PHP Library"
php-library = "MongoDB PHP Library"
mdb-server = "MongoDB Server"
api = "https://www.mongodb.com/docs/php-library/current/reference"
php-manual = "https://www.php.net/manual/en"
64 changes: 64 additions & 0 deletions source/includes/read/cursor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php
require 'vendor/autoload.php';

$uri = getenv('MONGODB_URI') ?: throw new RuntimeException('Set the MONGODB_URI variable to your Atlas URI that connects to the sample dataset');
$client = new MongoDB\Client($uri);

// start-db-coll
$collection = $client->sample_restaurants->restaurants;
// end-db-coll

// Iterates over and prints all documents that have a "name" value of "Dunkin' Donuts"
// start-cursor-iterate
$cursor = $collection->find(['name' => 'Dunkin\' Donuts']);
foreach ($cursor as $doc) {
echo json_encode($doc) . PHP_EOL;
}
// end-cursor-iterate

// Retrieves and prints the first document stored in the cursor
// start-cursor-first
$cursor = $collection->find(['name' => 'Dunkin\' Donuts']);
echo json_encode($cursor->current());
// end-cursor-first

// Converts the documents stored in a cursor to an array
// start-cursor-array
$cursor = $collection->find(['name' => 'Dunkin\' Donuts']);
$array_results = $cursor->toArray();
// end-cursor-array

// Creates a collection with a maximum size and inserts documents representing vegetables
// start-capped-coll
$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);
// end-capped-coll

// Iterates over the initial query results and continues iterating until three documents are stored in the cursor
// by using a tailable cursor
// start-tailable
$cursor = $collection->find([], ['cursorType' => MongoDB\Operation\Find::TAILABLE]);

$docs_found = 0;
while ($docs_found < 3) {
foreach ($cursor as $doc) {
echo json_encode($doc) . PHP_EOL;
$docs_found++;
}

// Sleeps for 100 milliseconds before trying to access more documents
usleep(100000);
}
// end-tailable

1 change: 1 addition & 0 deletions source/read.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ Read Data from MongoDB

/read/retrieve
/read/project
/read/cursor

179 changes: 179 additions & 0 deletions source/read/cursor.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
.. _php-cursors:

=========================
Access Data From a Cursor
=========================

.. contents:: On this page
:local:
:backlinks: none
:depth: 1
:class: singlecol

.. facet::
:name: genre
:values: reference

.. meta::
:keywords: read, results, code example

Overview
--------

In this guide, you can learn how to access data from a **cursor** by using the
{+php-library+}.

A cursor is a mechanism that returns the results of a read operation in iterable
batches. Cursors reduce both memory consumption and network bandwidth usage by holding
only a subset of documents at any given time rather than returning all documents at
once.

Whenever the {+php-library+} performs a read operation by using the ``MongoDB\Collection::find()``
method, it returns the matching documents in a ``MongoDB\Driver\Cursor`` instance.

Sample Data
~~~~~~~~~~~

The examples in this guide use the ``restaurants`` collection in the ``sample_restaurants``
database from the :atlas:`Atlas sample datasets </sample-data>`. 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:

.. literalinclude:: /includes/read/cursor.php
:language: php
:dedent:
:start-after: start-db-coll
:end-before: end-db-coll

To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see the
:atlas:`Get Started with Atlas </getting-started>` guide.

.. _php-cursors-iterate:

Access Cursor Contents Iteratively
----------------------------------

To iterate over the contents of a ``MongoDB\Driver\Cursor`` instance, use a ``foreach`` loop.

The following example uses the ``MongoDB\Collection::find()`` method to retrieve all documents
in which the ``name`` value is ``'Dunkin' Donuts'``. It then prints each document from the
cursor returned by the ``find()`` method:

.. io-code-block::
:copyable:

.. input:: /includes/read/cursor.php
:start-after: start-cursor-iterate
:end-before: end-cursor-iterate
:language: php
:dedent:

.. output::
:visible: false

{"_id":{"$oid":"..."},..."name":"Dunkin' Donuts","restaurant_id":"40379573"}
{"_id":{"$oid":"..."},..."name":"Dunkin' Donuts","restaurant_id":"40363098"}
{"_id":{"$oid":"..."},..."name":"Dunkin' Donuts","restaurant_id":"40395071"}
...

Retrieve Documents Individually
-------------------------------

To retrieve an individual document from a cursor, call the ``current()`` method on
a ``MongoDB\Driver\Cursor`` instance. This method returns the document that the cursor
initially points to. You can continue to advance the cursor by calling the ``next()``
method, which instructs the cursor to point to the next retrieved document.

The following example finds all documents in a collection that have a ``name`` value
of ``'Dunkin' Donuts'``. Then, it prints the first retrieved document by calling the
``current()`` method on a cursor:

.. io-code-block::
:copyable:

.. input:: /includes/read/cursor.php
:start-after: start-cursor-first
:end-before: end-cursor-first
:language: php
:dedent:

.. output::

{"_id":{"$oid":"..."},..."name":"Dunkin' Donuts","restaurant_id":"40379573"}

Retrieve All Documents
----------------------

.. warning::

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, :ref:`access your cursor iteratively <php-cursors-iterate>`.

To retrieve all documents from a cursor, convert the cursor into an array as
shown in the following example:

.. literalinclude:: /includes/read/cursor.php
:language: php
:dedent:
:start-after: start-cursor-array
:end-before: end-cursor-array

Tailable Cursors
----------------

When querying on a :manual:`capped collection </core/capped-collections/>`, you
can use a **tailable cursor** that remains open after the client exhausts the
results in a cursor. To create a tailable cursor, set the ``cursorType`` option to
``MongoDB\Operation\Find::TAILABLE`` in an array. Then, pass the array as an options
parameter to the ``MongoDB\Collection::find()`` method.

For example, you can create a capped collection called ``vegetables`` that stores
documents representing vegetables, as shown in the following code:

.. literalinclude:: /includes/read/cursor.php
:language: php
:dedent:
:start-after: start-capped-coll
:end-before: end-capped-coll

The following code uses a tailable cursor to retrieve all documents in the ``vegetables``
collection. After the cursor is exhausted, it remains open until retrieving three documents:

.. io-code-block::
:copyable:

.. input:: /includes/read/cursor.php
:start-after: start-tailable
:end-before: end-tailable
:language: php
:dedent:

.. output::
:visible: false

{"_id":{"$oid":"..."},"name":"cauliflower"}
{"_id":{"$oid":"..."},"name":"zucchini"}

If you insert another document into the ``vegetables`` collection, the preceding code prints
the new document and closes the ``while`` loop.

To learn more about tailable cursors, see the :manual:`Tailable Cursors guide
</core/tailable-cursors/>` in the {+mdb-server+} manual.

Additional Information
----------------------

To learn more about read operations, see the :ref:`php-retrieve` guide.

To learn more about cursors, see the following pages in the PHP manual:

- `MongoDB\\Driver\\Cursor <{+php-manual+}/class.mongodb-driver-cursor.php>`__
- `MongoDB\\Driver\\Cursor::current() <{+php-manual+}/mongodb-driver-cursor.current.php>`__
- `MongoDB\\Driver\\Cursor::toArray() <{+php-manual+}/mongodb-driver-cursor.toarray.php>`__

API Documentation
~~~~~~~~~~~~~~~~~

To learn more about the ``find()`` method, see `MongoDB\\Collection::find()
<{+api+}/method/MongoDBCollection-find/>`__ in the API documentation.
Loading