Skip to content

Commit a4b3796

Browse files
authored
DOCSP-41980: Cursor guide (#110)
* DOCSP-41980: Cursor guide * edits * code edits * output * vale fix * MM feedback * edit * fix code ex * edit * JT feedback
1 parent e5973db commit a4b3796

File tree

4 files changed

+254
-0
lines changed

4 files changed

+254
-0
lines changed

snooty.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,4 @@ driver-short = "PHP library"
2929
stable-api = "Stable API"
3030
mdb-server = "MongoDB Server"
3131
api = "https://www.mongodb.com/docs/php-library/current/reference"
32+
php-manual = "https://www.php.net/manual/en"

source/includes/read/cursor.php

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
require 'vendor/autoload.php';
3+
4+
$uri = getenv('MONGODB_URI') ?: throw new RuntimeException('Set the MONGODB_URI variable to your Atlas URI that connects to the sample dataset');
5+
$client = new MongoDB\Client($uri);
6+
7+
// start-db-coll
8+
$collection = $client->sample_restaurants->restaurants;
9+
// end-db-coll
10+
11+
// Iterates over and prints all documents that have a "name" value of "Dunkin' Donuts"
12+
// start-cursor-iterate
13+
$cursor = $collection->find(['name' => 'Dunkin\' Donuts']);
14+
foreach ($cursor as $doc) {
15+
echo json_encode($doc) . PHP_EOL;
16+
}
17+
// end-cursor-iterate
18+
19+
// Retrieves and prints the first document stored in the cursor
20+
// start-cursor-first
21+
$cursor = $collection->find(['name' => 'Dunkin\' Donuts']);
22+
$cursor->rewind();
23+
echo json_encode($cursor->current());
24+
// end-cursor-first
25+
26+
// Converts the documents stored in a cursor to an array
27+
// start-cursor-array
28+
$cursor = $collection->find(['name' => 'Dunkin\' Donuts']);
29+
$array_results = $cursor->toArray();
30+
// end-cursor-array
31+
32+
// Creates a collection with a maximum size and inserts documents representing vegetables
33+
// start-capped-coll
34+
$db = $client->db;
35+
$create_coll = $db->createCollection(
36+
'vegetables',
37+
['capped' => true, 'size' => 1024 * 1024]
38+
);
39+
40+
$vegetables = [
41+
['name' => 'cauliflower'],
42+
['name' => 'zucchini']
43+
];
44+
45+
$collection = $db->vegetables;
46+
$result = $collection->insertMany($vegetables);
47+
// end-capped-coll
48+
49+
// Iterates over the initial query results and continues iterating until three documents are stored in the cursor
50+
// by using a tailable cursor
51+
// start-tailable
52+
$cursor = $collection->find([], ['cursorType' => MongoDB\Operation\Find::TAILABLE]);
53+
$cursor->rewind();
54+
55+
$docs_found = 0;
56+
while ($docs_found < 3) {
57+
if ($cursor->valid()) {
58+
$doc = $cursor->current();
59+
echo json_encode($doc) . PHP_EOL;
60+
$docs_found++;
61+
}
62+
$cursor->next();
63+
}
64+
// end-tailable

source/read.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Read Data from MongoDB
1010

1111
/read/retrieve
1212
/read/project
13+
/read/cursor
1314
/read/count
1415
/read/specify-documents-to-return
1516
/read/specify-a-query

source/read/cursor.txt

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
.. _php-cursors:
2+
3+
=========================
4+
Access Data From a Cursor
5+
=========================
6+
7+
.. contents:: On this page
8+
:local:
9+
:backlinks: none
10+
:depth: 1
11+
:class: singlecol
12+
13+
.. facet::
14+
:name: genre
15+
:values: reference
16+
17+
.. meta::
18+
:keywords: read, results, code example
19+
20+
Overview
21+
--------
22+
23+
In this guide, you can learn how to access data from a **cursor** by using the
24+
{+php-library+}.
25+
26+
A cursor is a mechanism that returns the results of a read operation in iterable
27+
batches. Cursors reduce both memory consumption and the number of server requests
28+
by holding only a subset of documents at any given time, rather than returning all
29+
documents at once.
30+
31+
Whenever the {+php-library+} performs a read operation by using the ``MongoDB\Collection::find()``
32+
method, it returns the matching documents in a ``MongoDB\Driver\Cursor`` instance.
33+
34+
Sample Data
35+
~~~~~~~~~~~
36+
37+
The examples in this guide use the ``restaurants`` collection in the ``sample_restaurants``
38+
database from the :atlas:`Atlas sample datasets </sample-data>`. To access this collection
39+
from your PHP application, instantiate a ``MongoDB\Client`` that connects to an Atlas cluster
40+
and assign the following value to your ``$collection`` variable:
41+
42+
.. literalinclude:: /includes/read/cursor.php
43+
:language: php
44+
:dedent:
45+
:start-after: start-db-coll
46+
:end-before: end-db-coll
47+
48+
To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see the
49+
:atlas:`Get Started with Atlas </getting-started>` guide.
50+
51+
.. _php-cursors-iterate:
52+
53+
Access Cursor Contents Iteratively
54+
----------------------------------
55+
56+
The ``MongoDB\Driver\Cursor`` class implements the ``Iterator`` interface, so you
57+
can use a ``foreach`` loop to iterate through its contents.
58+
59+
The following example uses the ``MongoDB\Collection::find()`` method to retrieve all documents
60+
in which the ``name`` field value is ``'Dunkin' Donuts'``. It then prints each document from the
61+
cursor returned by the ``find()`` method:
62+
63+
.. io-code-block::
64+
:copyable:
65+
66+
.. input:: /includes/read/cursor.php
67+
:start-after: start-cursor-iterate
68+
:end-before: end-cursor-iterate
69+
:language: php
70+
:dedent:
71+
72+
.. output::
73+
:visible: false
74+
75+
{"_id":{"$oid":"..."},..."name":"Dunkin' Donuts","restaurant_id":"40379573"}
76+
{"_id":{"$oid":"..."},..."name":"Dunkin' Donuts","restaurant_id":"40363098"}
77+
{"_id":{"$oid":"..."},..."name":"Dunkin' Donuts","restaurant_id":"40395071"}
78+
...
79+
80+
Retrieve Documents Individually
81+
-------------------------------
82+
83+
To retrieve an individual document from a cursor, call the ``current()`` method on
84+
a ``MongoDB\Driver\Cursor`` instance. This method returns the document that the cursor
85+
initially points to. You can continue to advance the cursor by calling the ``next()``
86+
method, which instructs the cursor to point to the next retrieved document.
87+
88+
The following example finds all documents in which the ``name`` field value is
89+
``'Dunkin' Donuts'``. Then, it prints the first retrieved document by calling the
90+
``current()`` method on a cursor:
91+
92+
.. io-code-block::
93+
:copyable:
94+
95+
.. input:: /includes/read/cursor.php
96+
:start-after: start-cursor-first
97+
:end-before: end-cursor-first
98+
:language: php
99+
:dedent:
100+
101+
.. output::
102+
:visible: false
103+
104+
{"_id":{"$oid":"..."},..."name":"Dunkin' Donuts","restaurant_id":"40379573"}
105+
106+
Retrieve All Documents
107+
----------------------
108+
109+
.. warning::
110+
111+
If the number and size of documents returned by your query exceeds available
112+
application memory, your program will crash. If you expect a large result
113+
set, :ref:`access your cursor iteratively <php-cursors-iterate>`.
114+
115+
To retrieve all documents from a cursor, convert the cursor into an array by using
116+
either of the following methods:
117+
118+
- ``MongoDB\\Driver\\Cursor::toArray()``: Call on a ``MongoDB\Driver\Cursor`` object
119+
- ``iterator_to_array()``: Pass a ``MongoDB\Driver\Cursor`` object as a parameter
120+
121+
The following example calls the ``toArray()`` method on a cursor to store its results
122+
in an array:
123+
124+
.. literalinclude:: /includes/read/cursor.php
125+
:language: php
126+
:dedent:
127+
:start-after: start-cursor-array
128+
:end-before: end-cursor-array
129+
130+
Tailable Cursors
131+
----------------
132+
133+
When querying on a :manual:`capped collection </core/capped-collections/>`, you
134+
can use a **tailable cursor** that remains open after the client exhausts the
135+
results in a cursor. To create a tailable cursor, set the ``cursorType`` option to
136+
``MongoDB\Operation\Find::TAILABLE`` in an array. Then, pass the array as an options
137+
parameter to the ``MongoDB\Collection::find()`` method.
138+
139+
For example, you can create a capped collection called ``vegetables`` that stores
140+
documents representing vegetables, as shown in the following code:
141+
142+
.. literalinclude:: /includes/read/cursor.php
143+
:language: php
144+
:dedent:
145+
:start-after: start-capped-coll
146+
:end-before: end-capped-coll
147+
148+
The following code uses a tailable cursor to retrieve all documents in the ``vegetables``
149+
collection. After the cursor is exhausted, it remains open until retrieving three documents:
150+
151+
.. io-code-block::
152+
:copyable:
153+
154+
.. input:: /includes/read/cursor.php
155+
:start-after: start-tailable
156+
:end-before: end-tailable
157+
:language: php
158+
:dedent:
159+
160+
.. output::
161+
:visible: false
162+
163+
{"_id":{"$oid":"..."},"name":"cauliflower"}
164+
{"_id":{"$oid":"..."},"name":"zucchini"}
165+
166+
If you insert another document into the ``vegetables`` collection, the preceding code prints
167+
the new document and closes the ``while`` loop.
168+
169+
To learn more about tailable cursors, see :manual:`Tailable Cursors
170+
</core/tailable-cursors/>` in the {+mdb-server+} manual.
171+
172+
Additional Information
173+
----------------------
174+
175+
To learn more about read operations, see the :ref:`php-retrieve` guide.
176+
177+
To learn more about cursors, see the following pages in the PHP manual:
178+
179+
- `MongoDB\\Driver\\Cursor <{+php-manual+}/class.mongodb-driver-cursor.php>`__
180+
- `MongoDB\\Driver\\Cursor::current() <{+php-manual+}/mongodb-driver-cursor.current.php>`__
181+
- `MongoDB\\Driver\\Cursor::toArray() <{+php-manual+}/mongodb-driver-cursor.toarray.php>`__
182+
- `iterator_to_array() <{+php-manual+}/function.iterator-to-array.php>`__
183+
184+
API Documentation
185+
~~~~~~~~~~~~~~~~~
186+
187+
To learn more about the ``find()`` method, see the API documentation for
188+
`MongoDB\\Collection::find() <{+api+}/method/MongoDBCollection-find/>`__.

0 commit comments

Comments
 (0)