|
1 | 1 | .. _golang-watch-changes: |
2 | 2 | .. _golang-monitor-changes: |
3 | 3 | .. _golang-watch: |
4 | | -.. _golang-usageex-monitor-changes: |
5 | 4 |
|
6 | 5 | ================================ |
7 | 6 | Monitor Data with Change Streams |
8 | 7 | ================================ |
9 | 8 |
|
10 | | -.. TODO |
| 9 | +.. facet:: |
| 10 | + :name: genre |
| 11 | + :values: reference |
| 12 | + |
| 13 | +.. meta:: |
| 14 | + :keywords: code example, delta |
| 15 | + :description: Learn how to monitor document changes in MongoDB by using change streams, including opening streams and modifying output with pipelines and options. |
| 16 | + |
| 17 | +.. contents:: On this page |
| 18 | + :local: |
| 19 | + :backlinks: none |
| 20 | + :depth: 2 |
| 21 | + :class: singlecol |
| 22 | + |
| 23 | +Overview |
| 24 | +-------- |
| 25 | + |
| 26 | +In this guide, you can learn how to use a **change stream** to monitor real-time |
| 27 | +changes to your database. A change stream is a MongoDB Server feature that |
| 28 | +allows your application to subscribe to data changes on a collection, database, |
| 29 | +or deployment. |
| 30 | + |
| 31 | +A change stream outputs new change events, providing access to real-time data |
| 32 | +changes. You can open a change stream on a collection, database, or client |
| 33 | +object. |
| 34 | + |
| 35 | +Sample Data |
| 36 | +~~~~~~~~~~~ |
| 37 | + |
| 38 | +The examples in this guide use the following ``Course`` struct as a model for |
| 39 | +documents in the ``courses`` collection: |
| 40 | + |
| 41 | +.. literalinclude:: /includes/fundamentals/code-snippets/CRUD/changeStream.go |
| 42 | + :start-after: begin struct |
| 43 | + :end-before: end struct |
| 44 | + :language: go |
| 45 | + :dedent: |
| 46 | + |
| 47 | +To run the examples in this guide, load these documents into the ``courses`` |
| 48 | +collection in the ``db`` database by using the following snippet: |
| 49 | + |
| 50 | +.. literalinclude:: /includes/fundamentals/code-snippets/CRUD/changeStream.go |
| 51 | + :language: go |
| 52 | + :dedent: |
| 53 | + :start-after: begin insertDocs |
| 54 | + :end-before: end insertDocs |
| 55 | + |
| 56 | +.. include:: /includes/fundamentals/automatic-db-coll-creation.rst |
| 57 | + |
| 58 | +Each document contains a description of a university course that includes the |
| 59 | +course title and maximum enrollment, corresponding to the ``title`` and |
| 60 | +``enrollment`` fields in each document. |
| 61 | + |
| 62 | +.. note:: |
| 63 | + |
| 64 | + Each example output shows truncated ``_data``, ``clusterTime``, and |
| 65 | + ``ObjectID`` values because the driver generates them uniquely. |
| 66 | + |
| 67 | +Open a Change Stream |
| 68 | +-------------------- |
| 69 | + |
| 70 | +You can watch for changes in MongoDB by using the ``Watch()`` method on the |
| 71 | +following objects: |
| 72 | + |
| 73 | +- **Collection**: Monitor changes to a specific collection |
| 74 | +- **Database**: Monitor changes to all collections in a database |
| 75 | +- **MongoClient**: Monitor changes across all databases |
| 76 | + |
| 77 | +For each object, the ``Watch()`` method opens a change stream to emit change |
| 78 | +event documents when they occur. |
| 79 | + |
| 80 | +The ``Watch()`` method requires a context parameter and a pipeline parameter. To |
| 81 | +return all changes, pass in an empty ``Pipeline`` object. |
| 82 | + |
| 83 | +The ``Watch()`` method optionally takes an aggregation pipeline which consists |
| 84 | +of an array of aggregation stages as the first parameter. The aggregation stages |
| 85 | +filter and transform the change events. |
| 86 | + |
| 87 | +Example |
| 88 | +~~~~~~~ |
| 89 | + |
| 90 | +The following example opens a change stream on the ``courses`` collection and |
| 91 | +prints the change stream events as they occur: |
| 92 | + |
| 93 | +.. literalinclude:: /includes/fundamentals/code-snippets/CRUD/changeStream.go |
| 94 | + :language: go |
| 95 | + :dedent: |
| 96 | + :start-after: begin open stream |
| 97 | + :end-before: end open stream |
| 98 | + |
| 99 | +If you modify the ``courses`` collection in a separate program or shell, this |
| 100 | +code prints your changes as they occur. Inserting a document with a ``title`` |
| 101 | +value of ``"Advanced Screenwriting"`` and an ``enrollment`` value of ``20`` |
| 102 | +results in the following change event: |
| 103 | + |
| 104 | +.. code-block:: none |
| 105 | + :copyable: false |
| 106 | + |
| 107 | + map[_id:map[_data:...] clusterTime: {...} |
| 108 | + documentKey:map[_id:ObjectID("...")] fullDocument:map[_id:ObjectID("...") |
| 109 | + enrollment:20 title:Advanced Screenwriting] ns: map[coll:courses db:db] |
| 110 | + operationType:insert] |
| 111 | + |
| 112 | +To view a fully runnable example, see :ref:`Open a Change Stream Example: |
| 113 | +Full File <golang-change-streams-full-file>` section in this guide. |
| 114 | + |
| 115 | +Filter Change Events |
| 116 | +~~~~~~~~~~~~~~~~~~~~ |
| 117 | + |
| 118 | +Use the pipeline parameter to modify the change stream output. This parameter |
| 119 | +allows you to only watch for certain change events. Format the pipeline |
| 120 | +parameter as an array of documents, with each document representing an |
| 121 | +aggregation stage. |
| 122 | + |
| 123 | +You can use the following pipeline stages in this parameter: |
| 124 | + |
| 125 | +- ``$addFields`` |
| 126 | +- ``$match`` |
| 127 | +- ``$project`` |
| 128 | +- ``$replaceRoot`` |
| 129 | +- ``$replaceWith`` |
| 130 | +- ``$redact`` |
| 131 | +- ``$set`` |
| 132 | +- ``$unset`` |
| 133 | + |
| 134 | +The following example opens a change stream on the ``db`` database but only |
| 135 | +watches for new delete operations: |
| 136 | + |
| 137 | +.. literalinclude:: /includes/fundamentals/code-snippets/CRUD/changeStream.go |
| 138 | + :language: go |
| 139 | + :dedent: |
| 140 | + :start-after: begin delete events |
| 141 | + :end-before: end delete events |
| 142 | + |
| 143 | +.. note:: |
| 144 | + |
| 145 | + The ``Watch()`` method was called on the ``db`` database, so the code outputs |
| 146 | + new delete operations on any collection within this database. |
| 147 | + |
| 148 | +.. _golang-usageex-monitor-changes: |
| 149 | +.. _golang-change-streams-full-file: |
| 150 | + |
| 151 | +Open a Change Stream Example: Full File |
| 152 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 153 | + |
| 154 | +.. include:: /includes/usage-examples/example-intro.rst |
| 155 | + |
| 156 | +The following example opens a change stream on the ``restaurants`` collection |
| 157 | +and prints inserted documents: |
| 158 | + |
| 159 | +.. literalinclude:: /includes/usage-examples/code-snippets/watch.go |
| 160 | + :start-after: begin watch |
| 161 | + :end-before: end watch |
| 162 | + :emphasize-lines: 7 |
| 163 | + :language: go |
| 164 | + :dedent: |
| 165 | + |
| 166 | +View a `fully runnable example. <{+example+}/watch.go>`__ |
| 167 | + |
| 168 | +Expected Result |
| 169 | +^^^^^^^^^^^^^^^ |
| 170 | + |
| 171 | +.. TODO - when porting over all usage examples, ensure this link is correct. |
| 172 | + |
| 173 | +After you run the full example, run the :ref:`Insert a Document full file |
| 174 | +example <golang-insert-one>` in a different shell. When you run the insert |
| 175 | +operation, you see output similar to the following: |
| 176 | + |
| 177 | +.. code-block:: json |
| 178 | + :copyable: false |
| 179 | + |
| 180 | + // results truncated { |
| 181 | + "_id": ..., "name": "8282", "cuisine": "Korean" |
| 182 | + } |
| 183 | + |
| 184 | +.. important:: |
| 185 | + |
| 186 | + When you finish working with this usage example, make sure to shut it down by |
| 187 | + closing your terminal. |
| 188 | + |
| 189 | +Configure Change Stream Options |
| 190 | +------------------------------- |
| 191 | + |
| 192 | +Use the ``options`` parameter to modify the behavior of the ``Watch()`` method. |
| 193 | + |
| 194 | +You can specify the following options for the ``Watch()`` method: |
| 195 | + |
| 196 | +- ``ResumeAfter`` |
| 197 | +- ``StartAfter`` |
| 198 | +- ``FullDocument`` |
| 199 | +- ``FullDocumentBeforeChange`` |
| 200 | +- ``BatchSize`` |
| 201 | +- ``MaxAwaitTime`` |
| 202 | +- ``Collation`` |
| 203 | +- ``StartAtOperationTime`` |
| 204 | +- ``Comment`` |
| 205 | +- ``ShowExpandedEvents`` |
| 206 | +- ``Custom`` |
| 207 | +- ``CustomPipeline`` |
| 208 | + |
| 209 | +For more information on these options, see the :manual:`db.collection.watch() </reference/method/db.collection.watch/>` |
| 210 | +entry in the Server manual. |
| 211 | + |
| 212 | +Pre- and Post-Images |
| 213 | +~~~~~~~~~~~~~~~~~~~~ |
| 214 | + |
| 215 | +When you perform any CRUD operation on a collection, by default, the |
| 216 | +corresponding change event document contains only the delta of the fields |
| 217 | +modified by the operation. You can see the full document before and after a |
| 218 | +change, in addition to the delta, by specifying settings in the ``options`` |
| 219 | +parameter of the ``Watch()`` method. |
| 220 | + |
| 221 | +If you want to see a document's **post-image**, the full version of the document |
| 222 | +after a change, set the ``FullDocument`` field of the ``options`` parameter to |
| 223 | +one of the following values: |
| 224 | + |
| 225 | +- ``UpdateLookup``: The change event document includes a copy of the entire |
| 226 | + changed document. |
| 227 | +- ``WhenAvailable``: The change event document includes a post-image of the |
| 228 | + modified document for change events if the post-image is available. |
| 229 | +- ``Required``: The output is the same as for ``WhenAvailable``, but the driver |
| 230 | + raises a server-side error if the post-image is not available. |
| 231 | + |
| 232 | +If you want to see a document's **pre-image**, the full version of the document |
| 233 | +before a change, set the ``FullDocumentBeforeChange`` field of the ``options`` |
| 234 | +parameter to one of the following values: |
| 235 | + |
| 236 | +- ``WhenAvailable``: The change event document includes a pre-image of the |
| 237 | + modified document for change events if the pre-image is available. |
| 238 | +- ``Required``: The output is the same as for ``WhenAvailable``, but the driver |
| 239 | + raises a server-side error if the pre-image is not available. |
| 240 | + |
| 241 | +.. important:: |
| 242 | + |
| 243 | + To access document pre- and post-images, you must enable |
| 244 | + ``changeStreamPreAndPostImages`` for the collection. See the :manual:`Change |
| 245 | + Streams |
| 246 | + </reference/command/collMod/#change-streams-with-document-pre--and-post-images>` |
| 247 | + section of the collMod Database Command guide in the MongoDB Server manual |
| 248 | + for instructions and more information. |
| 249 | + |
| 250 | +.. note:: |
| 251 | + |
| 252 | + There is no pre-image for an inserted document and no post-image for a deleted document. |
| 253 | + |
| 254 | +Example |
| 255 | +~~~~~~~~ |
| 256 | + |
| 257 | +The following example calls the ``Watch()`` method on the ``courses`` |
| 258 | +collection. It specifies a value for the ``FullDocument`` field of the |
| 259 | +``options`` parameter to output a copy of the entire modified document, instead |
| 260 | +of only the changed fields: |
| 261 | + |
| 262 | +.. literalinclude:: /includes/fundamentals/code-snippets/CRUD/changeStream.go |
| 263 | + :language: go |
| 264 | + :dedent: |
| 265 | + :start-after: begin full document |
| 266 | + :end-before: end full document |
| 267 | + |
| 268 | +Updating the ``enrollment`` value of the document with the ``title`` of ``"World |
| 269 | +Fiction"`` from ``35`` to ``30`` results in the following change event: |
| 270 | + |
| 271 | +.. code-block:: none |
| 272 | + :copyable: false |
| 273 | + |
| 274 | + {"_id": {"_data": "..."},"operationType": "update","clusterTime": |
| 275 | + {"$timestamp": {"t":"...","i":"..."}},"fullDocument": {"_id": |
| 276 | + {"$oid":"..."},"title": "World Fiction","enrollment": {"$numberInt":"30"}}, |
| 277 | + "ns": {"db": "db","coll": "courses"},"documentKey": {"_id": {"$oid":"..."}}, |
| 278 | + "updateDescription": {"updatedFields": {"enrollment": {"$numberInt":"30"}}, |
| 279 | + "removedFields": [],"truncatedArrays": []}} |
| 280 | + |
| 281 | +Without specifying the ``FullDocument`` option, the same update operation no |
| 282 | +longer outputs the ``"fullDocument"`` value in the change event document. |
| 283 | + |
| 284 | +Additional Information |
| 285 | +---------------------- |
| 286 | + |
| 287 | +For more information on change streams, see :manual:`Change Streams |
| 288 | +</changeStreams/>` in the Server manual. |
| 289 | + |
| 290 | +API Documentation |
| 291 | +~~~~~~~~~~~~~~~~~ |
| 292 | + |
| 293 | +To learn more about the ``Watch()`` method, see the following API |
| 294 | +documentation: |
| 295 | + |
| 296 | +- `Watch() for collections <{+api+}/mongo#Collection.Watch>`__ |
| 297 | +- `Watch() for databases <{+api+}/mongo#Database.Watch>`__ |
| 298 | +- `Watch() for clients <{+api+}/mongo#Client.Watch>`__ |
0 commit comments