-
Notifications
You must be signed in to change notification settings - Fork 34
DOCSP-41981: Change streams #113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
cc7851f
617bab8
a7d8c02
9e6770f
7c95a9f
fb90e5f
32c9698
f201d6a
9023630
22a882c
a0c484a
f265d0c
4dfb66c
2652852
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<?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 | ||
|
||
// Monitors and prints changes to the "restaurants" collection | ||
jmikola marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// start-open-change-stream | ||
$changeStream = $collection->watch(); | ||
|
||
foreach ($changeStream as $event) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This is why the PHPLIB docs had a Tailable Cursor Iteration tutorial. The existing examples in the I'm not sure if this script is ever intended to be executed in its entirety, or simply serve as an assortment of snippets to include in the rendered docs. But if you're using the proper approach to iterate the change stream, note that the first loop is unlikely to terminate on its own and that would prevent subsequent statements in the file from executing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I changed these loops to for loops and edited based on the examples you linked - let me know what you think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. New iteration examples look good. Thanks. |
||
echo json_encode($event) . PHP_EOL; | ||
jmikola marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
// end-open-change-stream | ||
|
||
// Updates a document that has a "name" value of "Blarney Castle" | ||
// start-update-for-change-stream | ||
$result = $collection->updateOne( | ||
['name' => 'Blarney Castle'], | ||
['$set' => ['cuisine' => 'Irish']] | ||
); | ||
// end-update-for-change-stream | ||
|
||
// Passes a pipeline argument to watch() to monitor only update operations | ||
// start-change-stream-pipeline | ||
$pipeline = [['$match' => ['operationType' => 'update']]]; | ||
$changeStream = $collection->watch($pipeline); | ||
|
||
foreach ($changeStream as $event) { | ||
echo json_encode($event) . PHP_EOL; | ||
} | ||
// end-change-stream-pipeline | ||
|
||
// Passes an options argument to watch() to include the post-image of updated documents | ||
// start-change-stream-post-image | ||
$options = ['fullDocument' => MongoDB\Operation\Watch::FULL_DOCUMENT_UPDATE_LOOKUP]; | ||
$changeStream = $collection->watch([], $options); | ||
|
||
foreach ($changeStream as $event) { | ||
echo json_encode($event) . PHP_EOL; | ||
} | ||
// end-change-stream-post-image | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,4 +10,5 @@ Read Data from MongoDB | |
|
||
/read/retrieve | ||
/read/project | ||
/read/change-streams | ||
|
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,254 @@ | ||||||||||
.. _php-change-streams: | ||||||||||
|
||||||||||
==================== | ||||||||||
Monitor Data Changes | ||||||||||
==================== | ||||||||||
|
||||||||||
.. contents:: On this page | ||||||||||
:local: | ||||||||||
:backlinks: none | ||||||||||
:depth: 2 | ||||||||||
:class: singlecol | ||||||||||
|
||||||||||
.. facet:: | ||||||||||
:name: genre | ||||||||||
:values: reference | ||||||||||
|
||||||||||
.. meta:: | ||||||||||
:keywords: watch, code example | ||||||||||
|
||||||||||
Overview | ||||||||||
-------- | ||||||||||
|
||||||||||
In this guide, you can learn how to use a **change stream** to monitor real-time | ||||||||||
changes to your data. A change stream is a {+mdb-server+} feature that | ||||||||||
allows your application to subscribe to data changes on a collection, database, | ||||||||||
or deployment. | ||||||||||
|
||||||||||
When using the {+php-library+}, you can instantiate a ``MongoDB\ChangeStream`` to | ||||||||||
monitor data changes. | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
|
||||||||||
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: | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Also, since you're referring to a variable by name here, would it make sense to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My objection was with the word "value" in "assign the following value" because The code here is using the If it's kosher to write "assign the following to your Note: In the PHPLIB docs I've historically used the
Creation of the |
||||||||||
|
||||||||||
.. literalinclude:: /includes/read/change-streams.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. | ||||||||||
|
||||||||||
Open a Change Stream | ||||||||||
-------------------- | ||||||||||
|
||||||||||
To open a change stream, call the ``watch()`` method. The instance on which you | ||||||||||
call the ``watch()`` method determines the scope of events that the change | ||||||||||
stream monitors. You can call the ``watch()`` method on instances of the following | ||||||||||
classes: | ||||||||||
|
||||||||||
- ``MongoDB\Client``: Monitor all changes in the MongoDB deployment | ||||||||||
- ``MongoDB\Database``: Monitor changes in all collections in the database | ||||||||||
- ``MongoDB\Collection``: Monitor changes in the collection | ||||||||||
|
||||||||||
The following example opens a change stream on the ``restaurants`` collection | ||||||||||
and outputs changes as they occur: | ||||||||||
|
||||||||||
.. literalinclude:: /includes/read/change-streams.php | ||||||||||
:start-after: start-open-change-stream | ||||||||||
:end-before: end-open-change-stream | ||||||||||
:language: php | ||||||||||
:dedent: | ||||||||||
|
||||||||||
To begin watching for changes, run the preceding code. Then, in a separate | ||||||||||
application or shell, modify the ``restaurants`` collection. The following | ||||||||||
example updates a document that has a ``name`` field value of ``'Blarney Castle'``: | ||||||||||
|
||||||||||
.. _php-change-stream-update: | ||||||||||
|
||||||||||
.. literalinclude:: /includes/read/change-streams.php | ||||||||||
:start-after: start-update-for-change-stream | ||||||||||
:end-before: end-update-for-change-stream | ||||||||||
:language: php | ||||||||||
:dedent: | ||||||||||
|
||||||||||
When you update the collection, the change stream application prints the change | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Something that just occurred to me: should this tutorial advise users to run this PHP code through a shell/terminal? Users would likely run into issues trying to execute the I'm curious if there's language from other language tutorials (assuming this was adapted from existing content) we can use. The most straightforward way to address this might be to consistently refer to "shell process" instead of "application or shell" for all of the code examples (no harm in using that for the update example as well). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We use "application" pretty consistently across all docs, but I agree that it makes sense to suggest running the application from the shell. I updated all mentions of running the application on this page to clarify that |
||||||||||
as it occurs. The printed change event resembles the following output: | ||||||||||
|
||||||||||
.. code-block:: bash | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. S: change the type to |
||||||||||
:copyable: false | ||||||||||
|
||||||||||
{"_id":{"_data":"..."},"operationType":"update","clusterTime":{"$timestamp":{...}, | ||||||||||
"wallTime":{"$date":...},"ns":{"db":"sample_restaurants","coll":"restaurants"}, | ||||||||||
"documentKey":{"_id":{"$oid":"..."}},"updateDescription":{"updatedFields": | ||||||||||
{"cuisine":"Irish"},"removedFields":[],"truncatedArrays":[]}}} | ||||||||||
jmikola marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
|
||||||||||
Modify the Change Stream Output | ||||||||||
------------------------------- | ||||||||||
|
||||||||||
To modify the change stream output, you can pass pipeline stages in an array as a | ||||||||||
parameter to the ``watch()`` method. You can include the following stages in the | ||||||||||
array: | ||||||||||
|
||||||||||
- ``$addFields`` or ``$set``: Adds new fields to documents | ||||||||||
- ``$match``: Filters the documents | ||||||||||
- ``$project``: Projects a subset of the document fields | ||||||||||
- ``$replaceWith`` or ``$replaceRoot``: Replaces the input document with the | ||||||||||
specified document | ||||||||||
- ``$redact``: Restricts the contents of the documents | ||||||||||
- ``$unset``: Removes fields from documents | ||||||||||
|
||||||||||
The following passes a pipeline that includes the ``$match`` stage to the ``watch()`` | ||||||||||
method. This instructs the ``watch()`` method to output only update operations: | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
|
||||||||||
.. literalinclude:: /includes/read/change-streams.php | ||||||||||
:start-after: start-change-stream-pipeline | ||||||||||
:end-before: end-change-stream-pipeline | ||||||||||
:language: php | ||||||||||
:dedent: | ||||||||||
|
||||||||||
Modify ``watch()`` Behavior | ||||||||||
--------------------------- | ||||||||||
|
||||||||||
To modify the behavior of the ``watch()`` method, you can pass an options array | ||||||||||
as a parameter to ``watch()``. The following table describes some options you | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
can set in the array: | ||||||||||
|
||||||||||
.. list-table:: | ||||||||||
:widths: 30 70 | ||||||||||
:header-rows: 1 | ||||||||||
|
||||||||||
* - Option | ||||||||||
- Description | ||||||||||
|
||||||||||
* - ``fullDocument`` | ||||||||||
- | Specifies whether to show the full document after the change, rather | ||||||||||
than showing only the changes made to the document. To learn more about | ||||||||||
this option, see :ref:`php-change-stream-pre-post-image`. | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
|
||||||||||
* - ``fullDocumentBeforeChange`` | ||||||||||
- | Specifies whether to show the full document as it was before the change, rather | ||||||||||
than showing only the changes made to the document. To learn more about | ||||||||||
this option, see :ref:`php-change-stream-pre-post-image`. | ||||||||||
|
||||||||||
* - ``resumeAfter`` | ||||||||||
norareidy marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
- | Instructs ``watch()`` to resume returning changes after the | ||||||||||
operation specified in the resume token. | ||||||||||
| Each change stream event document includes a resume token as the ``_id`` | ||||||||||
field. Pass the entire ``_id`` field of the change event document that | ||||||||||
represents the operation you want to resume after. | ||||||||||
| This option is mutually exclusive with ``startAfter`` and ``startAtOperationTime``. | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. S: since you mention |
||||||||||
|
||||||||||
* - ``startAfter`` | ||||||||||
- | Instructs ``watch()`` to start a new change stream after the | ||||||||||
operation specified in the resume token. This field allows notifications to | ||||||||||
resume after an invalidate event. | ||||||||||
| Each change stream event document includes a resume token as the ``_id`` | ||||||||||
field. Pass the entire ``_id`` field of the change event document that | ||||||||||
represents the operation you want to resume after. | ||||||||||
| This option is mutually exclusive with ``resumeAfter`` and ``startAtOperationTime``. | ||||||||||
|
||||||||||
* - ``typeMap`` | ||||||||||
jmikola marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
- | The type map to apply to cursors, which determines how BSON documents are converted | ||||||||||
to PHP values. | ||||||||||
|
||||||||||
* - ``collation`` | ||||||||||
- | Sets the collation to use for the change stream cursor. | ||||||||||
|
||||||||||
For a full list of ``watch()`` options, see `MongoDB\\Collection::watch() | ||||||||||
<{+api+}/method/MongoDBCollection-watch/>`__ in the API | ||||||||||
documentation. | ||||||||||
|
||||||||||
.. _php-change-stream-pre-post-image: | ||||||||||
|
||||||||||
Include Pre-Images and Post-Images | ||||||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||||||
|
||||||||||
.. important:: | ||||||||||
|
||||||||||
You can enable pre-images and post-images on collections only if your | ||||||||||
deployment uses MongoDB v6.0 or later. | ||||||||||
|
||||||||||
By default, when you perform an operation on a collection, the | ||||||||||
corresponding change event includes only the delta of the fields | ||||||||||
modified by that operation. To see the full document before or after a | ||||||||||
change, specify the ``fullDocumentBeforeChange`` or the ``fullDocument`` | ||||||||||
options in an array parameter to ``watch()``. | ||||||||||
|
||||||||||
The **pre-image** is the full version of a document *before* a change. To include the | ||||||||||
pre-image in the change stream event, set the ``fullDocumentBeforeChange`` option | ||||||||||
to one of the following values: | ||||||||||
|
||||||||||
- ``MongoDB\Operation\Watch::FULL_DOCUMENT_BEFORE_CHANGE_WHEN_AVAILABLE``: The change event includes | ||||||||||
a pre-image of the modified document for change events. If the pre-image is not available, this | ||||||||||
change event field has a ``null`` value. | ||||||||||
- ``MongoDB\Operation\Watch::FULL_DOCUMENT_BEFORE_CHANGE_REQUIRED``: The change event includes a pre-image | ||||||||||
of the modified document for change events. If the pre-image is not available, the | ||||||||||
{+php-library+} raises an error. | ||||||||||
jmikola marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
|
||||||||||
The **post-image** is the full version of a document *after* a change. To include the | ||||||||||
post-image in the change stream event, set the ``fullDocument`` option to | ||||||||||
one of the following values: | ||||||||||
|
||||||||||
- ``MongoDB\Operation\Watch::FULL_DOCUMENT_UPDATE_LOOKUP``: The change event includes a | ||||||||||
copy of the entire changed document from some time after the change. | ||||||||||
- ``MongoDB\Operation\Watch::FULL_DOCUMENT_WHEN_AVAILABLE``: The change event includes | ||||||||||
a post-image of the modified document for change events only if the post-image is available. | ||||||||||
jmikola marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||
- ``MongoDB\Operation\Watch::FULL_DOCUMENT_REQUIRED``: The change event includes a post-image | ||||||||||
of the modified document for change events. If the post-image is not available, the | ||||||||||
{+php-library+} raises an error. | ||||||||||
|
||||||||||
The following example calls the ``watch()`` method on a collection and includes the post-image | ||||||||||
of updated documents by setting the ``fullDocument`` option: | ||||||||||
|
||||||||||
.. literalinclude:: /includes/read/change-streams.php | ||||||||||
:start-after: start-change-stream-post-image | ||||||||||
:end-before: end-change-stream-post-image | ||||||||||
:language: php | ||||||||||
:dedent: | ||||||||||
|
||||||||||
With the change stream application running, updating a document in the | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think "updating" should be "update". Per my earlier comment about pointing users away from using a web server, the following might be clearer:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added "in a separate shell" - "updating" makes more grammatical sense in this case There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
My mistake. I missed that the sentence continued with "prints a change event..." after the |
||||||||||
``restaurants`` collection by using the :ref:`preceding update example | ||||||||||
<php-change-stream-update>` prints a change event resembling the following | ||||||||||
code: | ||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
|
||||||||||
.. code-block:: bash | ||||||||||
:copyable: false | ||||||||||
:emphasize-lines: 2-5 | ||||||||||
|
||||||||||
{"_id":{"_data":"..."},"operationType":"update","clusterTime":...},"wallTime":{"$date":...}, | ||||||||||
"fullDocument":{"_id":{"$oid":"..."},"address": {"building":"202-24","coord": | ||||||||||
[-73.925044200000002093,40.559546199999999772], "street":"Rockaway Point Boulevard", | ||||||||||
"zipcode":"11697"},"borough":"Queens","cuisine":"Irish","grades":[...],"name":"Blarney Castle", | ||||||||||
"restaurant_id":"40366356"},"ns":{"db":"sample_restaurants","coll":"restaurants"}, | ||||||||||
"documentKey":{"_id":{"$oid":"..."}},"updateDescription":{"updatedFields":{"cuisine":"Irish"}, | ||||||||||
"removedFields":[],"truncatedArrays":[]}} | ||||||||||
|
||||||||||
.. tip:: | ||||||||||
|
||||||||||
To learn more about pre-images and post-images, see | ||||||||||
:manual:`Change Streams with Document Pre- and Post-Images </changeStreams#change-streams-with-document-pre--and-post-images>` | ||||||||||
in the {+mdb-server+} manual. | ||||||||||
|
||||||||||
Additional Information | ||||||||||
---------------------- | ||||||||||
|
||||||||||
To learn more about change streams, see :manual:`Change Streams | ||||||||||
</changeStreams>` in the {+mdb-server+} manual. | ||||||||||
|
||||||||||
API Documentation | ||||||||||
~~~~~~~~~~~~~~~~~ | ||||||||||
|
||||||||||
To learn more about any of the methods or types discussed in this | ||||||||||
guide, see the following API documentation: | ||||||||||
|
||||||||||
- `MongoDB\\Client::watch() <{+api+}/method/MongoDBClient-watch/>`__ | ||||||||||
- `MongoDB\\Database::watch() <{+api+}/method/MongoDBDatabase-watch/>`__ | ||||||||||
- `MongoDB\\Collection::watch() <{+api+}/method/MongoDBCollection-watch/>`__ | ||||||||||
- `MongoDB\\Collection::updateOne() <{+api+}/method/MongoDBCollection-updateOne/>`__ |
Uh oh!
There was an error while loading. Please reload this page.