Skip to content

Commit cc7851f

Browse files
committed
DOCSP-41981: Change streams
1 parent f4d7b49 commit cc7851f

File tree

3 files changed

+305
-0
lines changed

3 files changed

+305
-0
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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+
// Monitors and prints changes to the "restaurants" collection
12+
// start-open-change-stream
13+
$changeStream = $collection->watch();
14+
15+
foreach ($changeStream as $event) {
16+
echo json_encode($event), PHP_EOL;
17+
}
18+
// end-open-change-stream
19+
20+
// Updates a document that has a "name" value of "Blarney Castle"
21+
// start-update-for-change-stream
22+
$result = $collection->updateOne(
23+
['name' => 'Blarney Castle'],
24+
['$set' => ['cuisine' => 'Irish']]
25+
);
26+
// end-update-for-change-stream
27+
28+
// Passes a pipeline argument to watch() to monitor only update operations
29+
// start-change-stream-pipeline
30+
$pipeline = [['$match' => ['operationType' => 'update']]];
31+
$changeStream = $collection->watch($pipeline);
32+
33+
foreach ($changeStream as $event) {
34+
echo json_encode($event), PHP_EOL;
35+
}
36+
// end-change-stream-pipeline
37+
38+
// Passes an options argument to watch() to include the post-image of updated documents
39+
// start-change-stream-post-image
40+
$options = ['fullDocument' => 'updateLookup'];
41+
$changeStream = $collection->watch([], $options);
42+
43+
foreach ($changeStream as $event) {
44+
echo json_encode($event), PHP_EOL;
45+
}
46+
// end-change-stream-post-image
47+

source/read.txt

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

1111
/read/retrieve
1212
/read/project
13+
/read/change-streams
1314

source/read/change-streams.txt

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
.. _php-change-streams:
2+
3+
====================
4+
Monitor Data Changes
5+
====================
6+
7+
.. contents:: On this page
8+
:local:
9+
:backlinks: none
10+
:depth: 2
11+
:class: singlecol
12+
13+
.. facet::
14+
:name: genre
15+
:values: reference
16+
17+
.. meta::
18+
:keywords: watch, code example
19+
20+
Overview
21+
--------
22+
23+
In this guide, you can learn how to use a **change stream** to monitor real-time
24+
changes to your database. A change stream is a {+mdb-server+} feature that
25+
allows your application to subscribe to data changes on a collection, database,
26+
or deployment.
27+
28+
When using the {+driver-short+}, you can instantiate a ``MongoDB\ChangeStream`` to
29+
monitor data changes.
30+
31+
Sample Data
32+
~~~~~~~~~~~
33+
34+
The examples in this guide use the ``restaurants`` collection in the ``sample_restaurants``
35+
database from the :atlas:`Atlas sample datasets </sample-data>`. To access this collection
36+
from your PHP application, instantiate a ``MongoDB\Client`` that connects to an Atlas cluster
37+
and assign the following value to your ``collection`` variable:
38+
39+
.. literalinclude:: /includes/read/change-streams.php
40+
:language: php
41+
:dedent:
42+
:start-after: start-db-coll
43+
:end-before: end-db-coll
44+
45+
To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see the
46+
:atlas:`Get Started with Atlas </getting-started>` guide.
47+
48+
Open a Change Stream
49+
--------------------
50+
51+
To open a change stream, call the ``watch()`` method. The instance on which you
52+
call the ``watch()`` method on determines the scope of events that the change
53+
stream listens for. You can call the ``watch()`` method on the following
54+
classes:
55+
56+
- ``MongoDB\Client``: Monitor all changes in the MongoDB deployment
57+
- ``MongoDB\Database``: Monitor changes in all collections in the database
58+
- ``MongoDB\Collection``: Monitor changes in the collection
59+
60+
The following example opens a change stream on the ``restaurants`` collection
61+
and outputs changes as they occur:
62+
63+
.. literalinclude:: /includes/read/change-streams.php
64+
:start-after: start-open-change-stream
65+
:end-before: end-open-change-stream
66+
:language: php
67+
:dedent:
68+
69+
To begin watching for changes, run the preceding code. Then, in a separate
70+
application or shell, modify the ``restaurants`` collection. The following
71+
example updates a document that has a ``name`` field value of ``'Blarney Castle'``:
72+
73+
.. _php-change-stream-update:
74+
75+
.. literalinclude:: /includes/read/change-streams.php
76+
:start-after: start-update-for-change-stream
77+
:end-before: end-update-for-change-stream
78+
:language: php
79+
:dedent:
80+
81+
When you update the collection, the change stream application prints the change
82+
as it occurs. The printed change event resembles the following output:
83+
84+
.. code-block:: bash
85+
:copyable: false
86+
87+
{ "_id" : { "_data" : "..." }, "operationType" : "update", "clusterTime" :
88+
{ "$timestamp" : { ... }, "wallTime" : { "$date" : ... }, "ns" :
89+
{ "db" : "sample_restaurants", "coll" : "restaurants" }, "documentKey" :
90+
{ "_id" : { "$oid" : "..." } }, "updateDescription" : { "updatedFields" :
91+
{ "cuisine" : "Irish" }, "removedFields" : [ ], "truncatedArrays" : [ ] } }
92+
93+
Modify the Change Stream Output
94+
-------------------------------
95+
96+
To modify the change stream output, you can pass pipeline stages in an array as a
97+
parameter to the ``watch()`` method. You can include the following stages in the
98+
array:
99+
100+
- ``$addFields`` or ``$set``: Adds new fields to documents
101+
- ``$match``: Filters the documents
102+
- ``$project``: Projects a subset of the document fields
103+
- ``$replaceWith`` or ``$replaceRoot``: Replaces the input document with the
104+
specified document
105+
- ``$redact``: Restricts the contents of the documents
106+
- ``$unset``: Removes fields from documents
107+
108+
The following passes a pipeline that includes the ``$match`` stage to the ``watch()``
109+
method. This instructs the ``watch()`` method to output only update operations:
110+
111+
.. literalinclude:: /includes/read/change-streams.php
112+
:start-after: start-change-stream-pipeline
113+
:end-before: end-change-stream-pipeline
114+
:language: php
115+
:dedent:
116+
117+
Modify ``watch()`` Behavior
118+
---------------------------
119+
120+
To modify the behavior of the ``watch()`` method, you can pass an options array
121+
as a parameter to ``watch()``. The following table describes some of the options
122+
you can set in the array:
123+
124+
.. list-table::
125+
:widths: 30 70
126+
:header-rows: 1
127+
128+
* - Option
129+
- Description
130+
131+
* - ``fullDocument``
132+
- | Specifies whether to show the full document after the change, rather
133+
than showing only the changes made to the document. To learn more about
134+
this option, see :ref:`php-change-stream-pre-post-image`.
135+
136+
* - ``fullDocumentBeforeChange``
137+
- | Specifies whether to show the full document as it was before the change, rather
138+
than showing only the changes made to the document. To learn more about
139+
this option, see :ref:`php-change-stream-pre-post-image`.
140+
141+
* - ``resumeAfter``
142+
- | Instructs ``watch()`` to resume returning changes after the
143+
operation specified in the resume token.
144+
| Each change stream event document includes a resume token as the ``_id``
145+
field. Pass the entire ``_id`` field of the change event document that
146+
represents the operation you want to resume after.
147+
| ``resume_after`` is mutually exclusive with ``startAfter`` and ``startAtOperationTime``.
148+
149+
* - ``startAfter``
150+
- | Instructs ``watch()`` to start a new change stream after the
151+
operation specified in the resume token. This field allows notifications to
152+
resume after an invalidate event.
153+
| Each change stream event document includes a resume token as the ``_id``
154+
field. Pass the entire ``_id`` field of the change event document that
155+
represents the operation you want to resume after.
156+
| ``start_after`` is mutually exclusive with ``resume_after`` and ``start_at_operation_time``.
157+
158+
* - ``typeMap``
159+
- | Sets the maximum number of change events to return in each batch of the
160+
response from the MongoDB cluster.
161+
162+
* - ``collation``
163+
- | Sets the collation to use for the change stream cursor.
164+
165+
For a full list of ``watch()`` options, see `MongoDB\\Collection::watch()
166+
<{+api+}/reference/method/MongoDBCollection-watch/>`__ in the API
167+
documentation.
168+
169+
.. _php-change-stream-pre-post-image:
170+
171+
Include Pre-Images and Post-Images
172+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
173+
174+
.. important::
175+
176+
You can enable pre-images and post-images on collections only if your
177+
deployment uses MongoDB v6.0 or later.
178+
179+
By default, when you perform an operation on a collection, the
180+
corresponding change event includes only the delta of the fields
181+
modified by that operation. To see the full document before or after a
182+
change, specify the ``fullDocumentBeforeChange`` or the ``fullDocument``
183+
options in an array parameter to ``watch()``.
184+
185+
The **pre-image** is the full version of a document *before* a change. To include the
186+
pre-image in the change stream event, set the ``fullDocumentBeforeChange`` field
187+
to one of the following strings:
188+
189+
- ``MongoDB\Operation\Watch::FULL_DOCUMENT_BEFORE_CHANGE_WHEN_AVAILABLE``: The change event includes
190+
a pre-image of the modified document for change events. If the pre-image is not available, this
191+
change event field has a ``null`` value.
192+
- ``MongoDB\Operation\Watch::FULL_DOCUMENT_BEFORE_CHANGE_REQUIRED``: The change event includes a pre-image
193+
of the modified document for change events. If the pre-image is not available, the
194+
{+driver-short+} raises an error.
195+
196+
The **post-image** is the full version of a document *after* a change. To include the
197+
post-image in the change stream event, set the ``fullDocument`` field to
198+
one of the following strings:
199+
200+
- ``MongoDB\Operation\Watch::FULL_DOCUMENT_UPDATE_LOOKUP``: The change event includes a
201+
copy of the entire changed document from some time after the change.
202+
- ``MongoDB\Operation\Watch::FULL_DOCUMENT_WHEN_AVAILABLE``: The change event includes
203+
a post-image of the modified document for change events only if the post-image is available.
204+
- ``MongoDB\Operation\Watch::FULL_DOCUMENT_REQUIRED``: The change event includes a post-image
205+
of the modified document for change events. If the post-image is not available, the
206+
{+driver-short+} raises an error.
207+
208+
The following example calls the ``watch()`` method on a collection and includes the post-image
209+
of updated documents by setting the ``fullDocument`` option:
210+
211+
.. literalinclude:: /includes/read/change-streams.php
212+
:start-after: start-change-stream-post-image
213+
:end-before: end-change-stream-post-image
214+
:language: php
215+
:dedent:
216+
217+
With the change stream application running, updating a document in the
218+
``restaurants`` collection by using the :ref:`preceding update example
219+
<php-change-stream-update>` prints a change event resembling the following
220+
code:
221+
222+
.. code-block:: bash
223+
:copyable: false
224+
:emphasize-lines: 3,4,5,6
225+
226+
{ "_id" : { "_data" : "..." }, "operationType" : "update", "clusterTime" :
227+
{ "$timestamp" : { ... } }, "wallTime" : { "$date" : ... },
228+
"fullDocument" : { "_id" : { "$oid" : "..." }, "address" : { "building" : "202-24",
229+
"coord" : [ -73.925044200000002093, 40.559546199999999772 ], "street" :
230+
"Rockaway Point Boulevard", "zipcode" : "11697" }, "borough" : "Queens", "cuisine" :
231+
"Irish", "grades" : [ ... ], "name" : "Blarney Castle", "restaurant_id" : "40366356" },
232+
"ns" : { "db" : "sample_restaurants", "coll" : "restaurants" }, "documentKey" :
233+
{ "_id" : { "$oid" : "..." } }, "updateDescription" : { "updatedFields" :
234+
{ "cuisine" : "Irish" }, "removedFields" : [ ], "truncatedArrays" : [ ] } }
235+
236+
.. tip::
237+
238+
To learn more about pre-images and post-images, see
239+
:manual:`Change Streams with Document Pre- and Post-Images </changeStreams#change-streams-with-document-pre--and-post-images>`
240+
in the {+mdb-server+} manual.
241+
242+
Additional Information
243+
----------------------
244+
245+
To learn more about change streams, see :manual:`Change Streams
246+
</changeStreams>` in the {+mdb-server+} manual.
247+
248+
API Documentation
249+
~~~~~~~~~~~~~~~~~
250+
251+
To learn more about any of the methods or types discussed in this
252+
guide, see the following API documentation:
253+
254+
- `MongoDB\\Client::watch() <{+api+}/method/MongoDBClient-watch/>`__
255+
- `MongoDB\\Database::watch() <{+api+}/method/MongoDBDatabase-watch/>`__
256+
- `MongoDB\\Collection::watch() <{+api+}/method/MongoDBCollection-watch/>`__
257+
- `MongoDB\\Collection::updateOne() <{+api+}/method/MongoDBCollection-updateOne/>`__

0 commit comments

Comments
 (0)