|
| 1 | +.. _rust-change-streams-guide: |
| 2 | + |
| 3 | +=================== |
| 4 | +Open Change Streams |
| 5 | +=================== |
| 6 | + |
| 7 | +.. facet:: |
| 8 | + :name: genre |
| 9 | + :values: reference |
| 10 | + |
| 11 | +.. meta:: |
| 12 | + :keywords: monitor, delta, code example |
| 13 | + |
| 14 | +.. contents:: On this page |
| 15 | + :local: |
| 16 | + :backlinks: none |
| 17 | + :depth: 2 |
| 18 | + :class: singlecol |
| 19 | + |
| 20 | +Overview |
| 21 | +-------- |
| 22 | + |
| 23 | +In this guide, you can learn how to use a **change stream** to monitor |
| 24 | +real-time changes to your data. A change stream is a MongoDB Server feature |
| 25 | +that allows your application to subscribe to data changes on a single |
| 26 | +collection, database, or deployment. |
| 27 | + |
| 28 | +You can open a change stream to help perform the following actions: |
| 29 | + |
| 30 | +- Enable devices to track and react to events, such as motion-detecting |
| 31 | + cameras |
| 32 | +- Create an application that monitors changes in stock prices |
| 33 | +- Generate a log of employee activity for specific job positions |
| 34 | + |
| 35 | +You can specify a set of aggregation operators to filter and transform the data |
| 36 | +that your application receives. When connected to a MongoDB deployment v6.0 or later, |
| 37 | +you can also configure the events to include the document data before and after the |
| 38 | +change. |
| 39 | + |
| 40 | +To learn how to open and configure a change stream, navigate to the following |
| 41 | +sections: |
| 42 | + |
| 43 | +- :ref:`<rust-change-stream-data>` |
| 44 | +- :ref:`<rust-change-stream-open>` |
| 45 | +- :ref:`<rust-change-stream-aggregation>` |
| 46 | +- :ref:`<rust-change-stream-configure-pre-post>` |
| 47 | +- :ref:`<rust-change-stream-addtl-info>` |
| 48 | + |
| 49 | +.. _rust-change-stream-data: |
| 50 | + |
| 51 | +Sample Data |
| 52 | +----------- |
| 53 | + |
| 54 | +The examples in this guide monitor changes to the ``directors`` collection. |
| 55 | +Assume that this collection contains the following documents, which are modelled |
| 56 | +as structs: |
| 57 | + |
| 58 | +.. literalinclude:: /includes/fundamentals/code-snippets/crud/watch.rs |
| 59 | + :language: rust |
| 60 | + :dedent: |
| 61 | + :start-after: start-docs |
| 62 | + :end-before: end-docs |
| 63 | + |
| 64 | +.. tip:: |
| 65 | + |
| 66 | + To learn how to insert documents into a collection, see the :ref:`<rust-insert-guide>` |
| 67 | + guide. |
| 68 | + |
| 69 | +.. _rust-change-stream-open: |
| 70 | + |
| 71 | +Open a Change Stream |
| 72 | +-------------------- |
| 73 | + |
| 74 | +You can open a change stream to subscribe to specific types of data changes |
| 75 | +and produce change events in your application. |
| 76 | + |
| 77 | +To open a change stream, call the ``watch()`` method on a ``Collection``, |
| 78 | +``Database``, or ``Client`` instance. |
| 79 | + |
| 80 | +.. important:: |
| 81 | + |
| 82 | + Standalone MongoDB deployments don't support change streams because |
| 83 | + the feature requires a replica set oplog. To learn more about the oplog, |
| 84 | + see the :ref:`<replica-set-oplog>` page in the Server manual. |
| 85 | + |
| 86 | +The struct type on which you call the ``watch()`` method determines the scope of |
| 87 | +events that the change stream listens for. The following table describes the |
| 88 | +behavior of the ``watch()`` method based on its calling object: |
| 89 | + |
| 90 | +.. list-table:: |
| 91 | + :header-rows: 1 |
| 92 | + :stub-columns: 1 |
| 93 | + :class: compatibility-large |
| 94 | + |
| 95 | + * - Struct Type |
| 96 | + - Behavior of ``watch()`` |
| 97 | + |
| 98 | + * - ``Collection`` |
| 99 | + - | Monitors changes to the individual collection |
| 100 | + |
| 101 | + * - ``Database`` |
| 102 | + - | Monitors changes to all collections in the database |
| 103 | + |
| 104 | + * - ``Client`` |
| 105 | + - | Monitors all changes in the connected MongoDB deployment |
| 106 | + |
| 107 | +Example |
| 108 | +~~~~~~~ |
| 109 | + |
| 110 | +The following example opens a change stream on the ``directors`` collection. |
| 111 | +The code prints the operation type and modified document of each change event by |
| 112 | +accessing the ``operation_type`` and ``full_document`` fields of each ``ChangeStreamEvent`` |
| 113 | +instance: |
| 114 | + |
| 115 | +.. literalinclude:: /includes/fundamentals/code-snippets/crud/watch.rs |
| 116 | + :language: rust |
| 117 | + :dedent: |
| 118 | + :start-after: start-open |
| 119 | + :end-before: end-open |
| 120 | + |
| 121 | +.. tip:: |
| 122 | + |
| 123 | + For a full list of ``ChangeStreamEvent`` struct fields, see `ChangeStreamEvent |
| 124 | + <{+api+}/change_stream/event/struct.ChangeStreamEvent.html>`__ in the API documentation. |
| 125 | + |
| 126 | +If you insert a document into the ``directors`` collection in which the ``name`` value |
| 127 | +is ``"Wes Anderson"``, the preceding code produces the following output: |
| 128 | + |
| 129 | +.. code-block:: |
| 130 | + :copyable: false |
| 131 | + |
| 132 | + Operation performed: Insert |
| 133 | + Document: Some(Director { name: "Wes Anderson", movies: [...], oscar_noms: 7 }) |
| 134 | + |
| 135 | +.. _rust-change-stream-aggregation: |
| 136 | + |
| 137 | +Apply Aggregation Operators to your Change Stream |
| 138 | +------------------------------------------------- |
| 139 | + |
| 140 | +You can pass an aggregation pipeline as a parameter to the ``watch()`` method |
| 141 | +to specify which change events the change stream receives. |
| 142 | + |
| 143 | +To learn which aggregation operators your MongoDB Server version supports, see |
| 144 | +:ref:`<change-stream-modify-output>` in the Server manual. |
| 145 | + |
| 146 | +Example |
| 147 | +~~~~~~~ |
| 148 | + |
| 149 | +The following example creates an aggregation pipeline to filter for update |
| 150 | +operations. Then, the code passes the pipeline to the ``watch()`` method, |
| 151 | +configuring the change stream to only receive and print change events for |
| 152 | +update operations: |
| 153 | + |
| 154 | +.. literalinclude:: /includes/fundamentals/code-snippets/crud/watch.rs |
| 155 | + :language: rust |
| 156 | + :dedent: |
| 157 | + :start-after: start-pipeline |
| 158 | + :end-before: end-pipeline |
| 159 | + |
| 160 | +If you update the document in which the ``name`` value is ``"Todd Haynes"`` |
| 161 | +by increasing the value of the ``oscar_noms`` field, the preceding code |
| 162 | +produces the following output: |
| 163 | + |
| 164 | +.. code-block:: |
| 165 | + :copyable: false |
| 166 | + |
| 167 | + Update performed: Some(UpdateDescription { updated_fields: Document({ |
| 168 | + "oscar_noms": Int64(2)}), removed_fields: [], truncated_arrays: Some([]) }) |
| 169 | + |
| 170 | +.. tip:: |
| 171 | + |
| 172 | + To learn how to perform update operations, see the :ref:`<rust-change-guide>` |
| 173 | + guide. |
| 174 | + |
| 175 | +.. _rust-change-stream-configure-pre-post: |
| 176 | + |
| 177 | +Include Pre-Images and Post-Images |
| 178 | +---------------------------------- |
| 179 | + |
| 180 | +You can configure the change event to contain or omit the following data: |
| 181 | + |
| 182 | +- **Pre-image**: a document that represents the version of the |
| 183 | + document before the operation, if it exists |
| 184 | +- **Post-image**: a document that represents the version of the |
| 185 | + document after the operation, if it exists |
| 186 | + |
| 187 | +.. important:: |
| 188 | + |
| 189 | + You can enable pre- and post-images on collections only if your |
| 190 | + deployment uses MongoDB v6.0 or later. |
| 191 | + |
| 192 | +To receive change stream events that include a pre-image or post-image, you |
| 193 | +must perform the following actions: |
| 194 | + |
| 195 | +- Enable pre-images and post-images for the collection on your MongoDB |
| 196 | + deployment. |
| 197 | + |
| 198 | + .. tip:: |
| 199 | + |
| 200 | + To learn how to enable pre- and post-images on your deployment, see |
| 201 | + :manual:`Change Streams with Document Pre- and Post-Images </changeStreams/#change-streams-with-document-pre--and-post-images>` |
| 202 | + in the Server manual. |
| 203 | + |
| 204 | + To learn how to instruct the driver to create a collection with pre-images |
| 205 | + and post-images enabled, see the :ref:`<rust-change-stream-pre-post-collection>` |
| 206 | + section of this page. |
| 207 | + |
| 208 | +- Configure your change stream to retrieve either or both the pre-images and |
| 209 | + post-images. During this configuration, you can instruct the driver to require |
| 210 | + pre- and post-images or to only include them when available. |
| 211 | + |
| 212 | + .. tip:: |
| 213 | + |
| 214 | + To configure your change stream to record the pre-image in change |
| 215 | + events, see the :ref:`<rust-pre-image-example>` on this page. |
| 216 | + |
| 217 | + To configure your change stream to record the post-image in change |
| 218 | + events, see the :ref:`<rust-post-image-example>` on this page. |
| 219 | + |
| 220 | +.. _rust-change-stream-pre-post-collection: |
| 221 | + |
| 222 | +Create a Collection with Pre-Image and Post-Images Enabled |
| 223 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 224 | + |
| 225 | +To create a collection with the pre-image and post-image documents enabled, |
| 226 | +configure this option in a ``CreateCollectionOptions`` struct instance. To begin |
| 227 | +building a ``CreateCollectionOptions`` instance, call the ``CreateCollectionOptions::builder()`` |
| 228 | +method. |
| 229 | + |
| 230 | +.. note:: Instantiating Options |
| 231 | + |
| 232 | + The {+driver-short+} implements the Builder design pattern for the |
| 233 | + creation of many different types, including ``CreateCollectionOptions``. You |
| 234 | + can use the ``builder()`` method to construct an instance of each type |
| 235 | + by chaining option builder methods. |
| 236 | + |
| 237 | +When configuring your ``CreateCollectionOptions`` instance, you must use the |
| 238 | +``change_stream_pre_and_post_images()`` builder method. The following example |
| 239 | +uses this builder method to specify collection options and creates a |
| 240 | +collection for which pre- and post-images are available: |
| 241 | + |
| 242 | +.. literalinclude:: /includes/fundamentals/code-snippets/crud/watch.rs |
| 243 | + :language: rust |
| 244 | + :dedent: |
| 245 | + :start-after: start-create-coll |
| 246 | + :end-before: end-create-coll |
| 247 | + |
| 248 | +You can change the pre-image and post-image option in an existing collection |
| 249 | +by running the ``collMod`` command from the MongoDB Shell or from your application. |
| 250 | +To learn how to perform this operation, see the :ref:`<rust-run-command>` guide |
| 251 | +and the entry on :manual:`collMod </reference/command/collMod/>` in the Server manual. |
| 252 | + |
| 253 | +.. warning:: |
| 254 | + |
| 255 | + If you enabled pre-images or post-images on a collection, modifying |
| 256 | + these settings with ``collMod`` can cause existing change streams on |
| 257 | + that collection to terminate. |
| 258 | + |
| 259 | +.. _rust-pre-image-example: |
| 260 | + |
| 261 | +Pre-Image Configuration Example |
| 262 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 263 | + |
| 264 | +To configure a change stream that returns change events containing the pre-image, |
| 265 | +specify a ``ChangeStreamOptions`` struct instance. To begin building a ``ChangeStreamOptions`` |
| 266 | +instance, call the ``ChangeStreamOptions::builder()`` method. |
| 267 | + |
| 268 | +When configuring your ``ChangeStreamOptions`` instance to return the pre-image document, |
| 269 | +you must use the ``full_document_before_change()`` builder method. The following example |
| 270 | +specifies change stream options and creates a change stream that returns pre-image |
| 271 | +documents: |
| 272 | + |
| 273 | +.. literalinclude:: /includes/fundamentals/code-snippets/crud/watch.rs |
| 274 | + :language: rust |
| 275 | + :dedent: |
| 276 | + :start-after: start-pre |
| 277 | + :end-before: end-pre |
| 278 | + |
| 279 | +The preceding example passes a value of ``FullDocumentBeforeChangeType::Required`` |
| 280 | +to the ``full_document_before_change()`` builder method. This option configures the change |
| 281 | +stream to require pre-images for replace, update, and delete change events. If the pre-image |
| 282 | +is not available, the driver raises an error. |
| 283 | + |
| 284 | +If you update a document in which the ``name`` value is ``"Jane Campion"``, the change event |
| 285 | +produces the following output: |
| 286 | + |
| 287 | +.. code-block:: |
| 288 | + :copyable: false |
| 289 | + |
| 290 | + Operation performed: Update |
| 291 | + Pre-image: Some(Director { name: "Jane Campion", movies: ["The Piano", |
| 292 | + "Bright Star"], oscar_noms: 5 }) |
| 293 | + |
| 294 | +.. _rust-post-image-example: |
| 295 | + |
| 296 | +Post-Image Configuration Example |
| 297 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 298 | + |
| 299 | +To configure a change stream that returns change events containing the post-image, |
| 300 | +specify a ``ChangeStreamOptions`` struct instance. To begin building a ``ChangeStreamOptions`` |
| 301 | +instance, call the ``ChangeStreamOptions::builder()`` method. |
| 302 | + |
| 303 | +When configuring your ``ChangeStreamOptions`` instance to return the post-image document, |
| 304 | +you must use the ``full_document()`` builder method. The following example specifies change |
| 305 | +stream options and creates a change stream that returns post-image documents: |
| 306 | + |
| 307 | +.. literalinclude:: /includes/fundamentals/code-snippets/crud/watch.rs |
| 308 | + :language: rust |
| 309 | + :dedent: |
| 310 | + :start-after: start-post |
| 311 | + :end-before: end-post |
| 312 | + |
| 313 | +The preceding example passes a value of ``FullDocument::WhenAvailable`` to the ``full_document()`` |
| 314 | +builder method. This option configures the change stream to return post-images for replace, update, |
| 315 | +and delete change events if the post-image is available. |
| 316 | + |
| 317 | +If you delete the document in which the value of ``name`` is ``"Todd Haynes"``, the |
| 318 | +change event produces the following output: |
| 319 | + |
| 320 | +.. code-block:: |
| 321 | + :copyable: false |
| 322 | + |
| 323 | + Operation performed: Delete |
| 324 | + Post-image: None |
| 325 | + |
| 326 | +.. _rust-change-stream-addtl-info: |
| 327 | + |
| 328 | +Additional Information |
| 329 | +---------------------- |
| 330 | + |
| 331 | +API Documentation |
| 332 | +~~~~~~~~~~~~~~~~~ |
| 333 | + |
| 334 | +To learn more about any of the methods or types mentioned in this |
| 335 | +guide, see the following API documentation: |
| 336 | + |
| 337 | +- `watch() <{+api+}/struct.Collection.html#method.watch>`__ |
| 338 | +- `CreateCollectionOptions <{+api+}/options/struct.CreateCollectionOptions.html>`__ |
| 339 | +- `ChangeStreamOptions <{+api+}/options/struct.ChangeStreamOptions.html>`__ |
| 340 | +- `FullDocumentBeforeChangeType <{+api+}/options/enum.FullDocumentBeforeChangeType.html>`__ |
| 341 | +- `FullDocumentType <{+api+}/options/enum.FullDocumentType.html>`__ |
0 commit comments