Skip to content

Commit 265f3a0

Browse files
author
Chris Cho
authored
DOCSP-10436: address feedback on change streams usage example (#107)
* DOCSP-10436: address feedback on change streams usage example
1 parent 4a1c467 commit 265f3a0

File tree

2 files changed

+112
-44
lines changed

2 files changed

+112
-44
lines changed

source/code-snippets/usage-examples/changeStream.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ async function run() {
2323
console.log("received a change to the collection: \t", next);
2424
});
2525

26-
// wrap the setTimeout methods in a new Promise to wait for the timers to run
26+
// use a timeout to ensure the listener is registered before the insertOne
27+
// operation is called.
2728
await new Promise(resolve => {
28-
// wait for the event listener to register before inserting a document
2929
setTimeout(async () => {
3030
await collection.insertOne({
3131
test: "sample movie document",

source/usage-examples/changeStream.txt

Lines changed: 110 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8,60 +8,128 @@ Open a Change Stream
88
--------------------
99

1010
You can keep track of changes to data in MongoDB, such as changes to a
11-
collection, database, or deployment, by opening a :manual:`change
12-
stream</changeStreams/>`. A change stream allows applications to
13-
watch for changes to data and react to those changes. You can open a
14-
change stream by calling the :node-api:`Collection.watch()
15-
</Collection.html#watch>`, :node-api:`Db.watch() </Db.html#watch>`, or
16-
:node-api:`MongoClient.watch()</MongoClient.html#watch>` method.
17-
18-
The ``watch()`` method optionally takes a :manual:`pipeline
19-
</reference/operator/aggregation-pipeline/>`, an array of
20-
:manual:`stages </changeStreams/#modify-change-stream-output>`, as the
21-
first parameter to filter and transform the :manual:`change events
22-
</reference/change-events/>` output. ``watch()`` accepts an additional
23-
options object as the second parameter. By default, change streams only
24-
return the fields modified by an update operation, instead of the entire
25-
updated document. You can configure your change stream to also
26-
return the most current version of a document by setting the
27-
``fullDocument`` field of the options object to ``"updateLookup"``.
11+
collection, database, or deployment, by opening a **change stream**. A change
12+
stream allows applications to watch for changes to data and react to them.
13+
You can open a change stream by calling ``watch()`` method on
14+
a ``Collection``, ``Db``, or ``MongoClient`` object. The change stream
15+
returns **change event** documents when they occur.
16+
17+
The ``watch()`` method optionally takes an **aggregation pipeline** which
18+
consists of an array of **stages** as the first parameter to filter and
19+
transform the change events output as follows:.
20+
21+
.. code-block:: javascript
22+
23+
const pipeline = [ { $match: { runtime: { $lt: 15 } }, ];
24+
const changeStream = await collection.watch(pipeline);
25+
26+
The ``watch()`` method accepts an additional ``options`` object as the second
27+
parameter. Refer to the links at the end of this section for more
28+
information on the settings you can configure in this object.
29+
30+
The ``watch()`` method returns an instance of a ``ChangeStream``. You can
31+
call methods on the ChangeStream such as ``hasNext()`` to check for remaining
32+
documents in the stream, ``next()`` to request the next document in the
33+
stream, ``pause()`` to stop emitting events, ``resume()`` to continue to
34+
emit events, and ``close()`` to close the ChangeStream. You can also attach
35+
listener functions by calling the ``on()`` method on the instance. See the
36+
link to the ``ChangeStream`` API documentation below for more details on the
37+
available methods.
38+
39+
Visit the following resources for additional material on the classes and
40+
methods presented above:
41+
42+
- :manual:`change streams </changeStreams/>`
43+
- :manual:`change events </reference/change-events/>`
44+
- :manual:`aggregation pipeline </reference/operator/aggregation-pipeline/>`
45+
- :manual:`aggregation stages </changeStreams/#modify-change-stream-output>`
46+
- :node-api:`ChangeStream class API documentation <api/ChangeStream.html>`
47+
- :node-api:`Collection.watch() </Collection.html#watch>`,
48+
:node-api:`Db.watch() </Db.html#watch>`,
49+
:node-api:`MongoClient.watch() API documentation </MongoClient.html#watch>`
2850

2951
Process the Change Stream Events
3052
--------------------------------
3153

32-
You can capture events from a change stream with a listener
33-
function. Call the ``watch()`` command to get a ``ChangeStream`` instance.
34-
Add your listener function by calling the `EventEmitter.on()
35-
<https://nodejs.org/api/events.html#events_emitter_on_eventname_listener>`_
36-
method on that instance. Pass the string ``change`` as the first parameter
37-
and add your :mdn:`callback function <Glossary/Callback_function>` as
38-
the second parameter. The callback triggers when a change event is
39-
emitted, providing the next available document. You can specify logic in
40-
the callback to process the event document when it is received.
54+
You can capture events from a change stream using a listener function. Call
55+
the ``watch()`` command to get a ``ChangeStream`` instance. Add your listener
56+
function by calling the ``on()`` method on the instance, inherited from
57+
the Javascript ``EventEmitter`` class. Pass the string ``"change"`` as the
58+
first parameter and add your callback function as the second parameter as
59+
shown below:
60+
61+
.. code-block:: javascript
62+
63+
changeStream.on("change", (changeEvent) => { /* your callback function */ });
64+
65+
The callback function triggers when a change event is emitted. You can
66+
specify logic in the callback to process the event document when it is
67+
received.
68+
69+
To stop processing change events, call the
70+
:node-api:`close() </ChangeStream.html#close>` method on the ``ChangeStream``
71+
instance. This closes the change stream and frees resources.
4172

42-
Call the :node-api:`close() </ChangeStream.html#close>` method on the
43-
``ChangeStream`` instance to stop processing change events. This method
44-
closes the change stream and frees resources.
73+
.. code-block:: javascript
74+
75+
changeStream.close();
76+
77+
.. note::
78+
79+
For update operation change events, change streams only return the modified
80+
fields by default rather than the full updated document. You can configure
81+
your change stream to also return the most current version of the document
82+
by setting the ``fullDocument`` field of the options object to
83+
``"updateLookup"`` as follows:
84+
85+
.. code-block:: javascript
86+
87+
const changeStream = await collection.watch();
88+
const options = { fullDocument: "updateLookup" };
89+
changeStream.on("change", callbackFunction, options);
4590

4691
Example
4792
-------
4893

49-
The following example opens a change stream on the ``movies``
50-
collection. We create a listener function to receive and print change
51-
events that occur.
94+
The following example opens a change stream on the ``movies`` collection in
95+
the ``sample_mflix`` database. Let's create a listener function to receive and
96+
print change events that occur on the collection.
5297

53-
To emit a change event, we perform a change to the collection, such as
54-
insertion with ``insertOne()``. To prevent ``insertOne()`` from
55-
executing before the listener function can register, we create a timer
56-
that uses :mdn:`setTimeout <Web/API/WindowOrWorkerGlobalScope/setTimeout>`
57-
to wait 1 second. When you insert a document, the listener receives the
58-
corresponding event.
98+
First, open the change stream on the collection and then define a callback
99+
on the change stream using the ``on()`` method. Once set, generate a change
100+
event to be emitted by performing a change to the collection.
59101

60-
After that, we create a second timer to wait an additional second after
61-
the insertion of the document to close the ``ChangeStream`` instance
62-
using ``changeStream.close()``.
102+
To generate the change event on the collection, let's use ``insertOne()``
103+
method to add a new document. Since the ``insertOne()`` may run before the
104+
listener function can register, we use a timer, declared with ``setTimeout()``
105+
to wait one second before executing the insert.
106+
107+
We also use a second timer to wait an additional second after the insertion of
108+
the document to provide ample time for the change event to be received and
109+
the for the callback to complete its execution before closing the
110+
``ChangeStream`` instance using the ``close()`` method.
111+
112+
The timers used in this example are only necessary for this demonstration
113+
to make sure there is enough time to register listener and have the
114+
callback process the event before exiting.
63115

64116
.. include:: /includes/connect-guide-note.rst
65117

66118
.. literalinclude:: /code-snippets/usage-examples/changeStream.js
67-
:language: javascript :linenos:
119+
:language: javascript
120+
121+
If you run the example above, you should see output similar to the
122+
following:
123+
124+
.. code-block:: javascript
125+
126+
received a change to the collection: {
127+
_id: {
128+
_data: '825EC...'
129+
},
130+
operationType: 'insert',
131+
clusterTime: Timestamp { ... },
132+
fullDocument: { _id: 5ec3..., test: 'sample movie document' },
133+
ns: { db: 'sample_mflix', coll: 'movies' },
134+
documentKey: { _id: 5ec3... },
135+
}

0 commit comments

Comments
 (0)