Monitor Data Changes
On this page
Overview
In this guide, you can learn how to use the C driver to monitor a change stream, allowing you to view real-time changes to your data. A change stream is a MongoDB Server feature that publishes data changes on a collection, database, or deployment. Your application can subscribe to a change stream and use events to perform other actions.
Sample Data
The examples in this guide use the restaurants
collection in the sample_restaurants
database from the Atlas sample datasets. To learn how to create a
free MongoDB Atlas cluster and load the sample datasets, see the
Get Started with Atlas guide.
Open a Change Stream
To open a change stream, call one of the following functions that corresponds to the scope of events you want to observe:
mongoc_client_watch()
: Monitors all changes in the MongoDB deploymentmongoc_database_watch()
: Monitors changes in all collections in the databasemongoc_collection_watch()
: Monitors changes in the collection
Open a Change Stream Example
The following example opens a change stream on the restaurants
collection
and prints changes as they occur:
bson_t *pipeline = bson_new (); const bson_t *doc; mongoc_change_stream_t *change_stream = mongoc_collection_watch (collection, pipeline, NULL); while (true) { bson_error_t error; if (mongoc_change_stream_next (change_stream, &doc)) { char *str = bson_as_canonical_extended_json (doc, NULL); printf ("Received change: %s\n", str); bson_free (str); } else if (mongoc_change_stream_error_document (change_stream, &error, NULL)) { printf("Got error on change stream: %s\n", error.message); break; } } bson_destroy (pipeline); mongoc_change_stream_destroy (change_stream);
To begin watching for changes, run the application. Then, in a separate
application or shell, perform a write operation on the restaurants
collection. The
following example updates a document in which the value of the name
field is "Blarney Castle"
:
bson_t *filter = BCON_NEW ("name", BCON_UTF8 ("Blarney Castle")); bson_t *update = BCON_NEW("$set", "{", "cuisine", BCON_UTF8 ("Irish"), "}"); mongoc_collection_update_one (collection, filter, update, NULL, NULL, NULL);
When you update the collection, the change stream application prints the change as it occurs. The printed change event resembles the following:
{ "_id": { ... }, "operationType": "update", "clusterTime": { ... }, "ns": { "db": "sample_restaurants", "coll": "restaurants" }, "updateDescription": { "updatedFields": { "cuisine": "Irish" }, "removedFields": [], "truncatedArrays": [] } ... }
Modify the Change Stream Output
You can pass the pipeline
parameter to any watch function to modify the
change stream output. This parameter allows you to watch for only specified
change events. Format the parameter as a list of objects, where each object represents an
aggregation stage.
You can specify the following stages in the pipeline
parameter:
$addFields
$match
$project
$replaceRoot
$replaceWith
$redact
$set
$unset
Match Specific Events Example
The following example uses the pipeline
parameter to include a $match
stage
to open a change stream that records only update operations:
bson_t *pipeline = BCON_NEW ( "pipeline", "[", "{", "$match", "{", "operationType", BCON_UTF8 ("update"), "}", "}", "]"); const bson_t *doc; mongoc_change_stream_t *change_stream = mongoc_collection_watch (collection, pipeline, NULL); while (mongoc_change_stream_next (change_stream, &doc)) { char *str = bson_as_canonical_extended_json (doc, NULL); printf ("Received change: %s\n", str); bson_free (str); } bson_destroy (pipeline); mongoc_change_stream_destroy (change_stream);
To learn more about modifying your change stream output, see the Modify Change Stream Output section in the MongoDB Server manual.
Modify Watch Behavior
You can modify any watch function by passing options to the function call. If you don't specify any options, the driver does not customize the operation.
The following table describes options you can use to customize the behavior of the watch functions:
Option | Description |
---|---|
| Sets the number of documents to return per batch. |
| Specifies a comment to attach to the operation. |
| Sets the fullDocument value. To learn more, see the
Include Pre-Images and Post-Images section of this document. |
| Sets the fullDocumentBeforeChange value. To learn more, see the
Include Pre-Images and Post-Images section of this document. |
| Sets the maximum await execution time on the server for this operation, in
milliseconds. |
For a complete list of options you can use to configure the watch operation, see the watch method guide in the MongoDB Server manual.
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 your watch function call.
The pre-image is the full version of a document before a change. To include the
pre-image in the change stream event, pass one of the following values to the
fullDocumentBeforeChange
option:
whenAvailable
: The change event includes a pre-image of the modified document for change events only if the pre-image is available.required
: The change event includes a pre-image of the modified document for change events. If the pre-image is not available, the driver raises an error.
The post-image is the full version of a document after a change. To include the
post-image in the change stream event, pass one of the following values to the
fullDocument
option:
updateLookup
: The change event includes a copy of the entire changed document from some time after the change.whenAvailable
: The change event includes a post-image of the modified document for change events only if the post-image is available.required
: The change event includes a post-image of the modified document for change events. If the post-image is not available, the driver raises an error.
The following example calls the mongoc_collection_watch()
function on a collection and
includes the post-image of updated documents in the results by specifying the
fullDocument
option:
bson_t *pipeline = bson_new (); bson_t *opts = BCON_NEW ("fullDocument", BCON_UTF8 ("updateLookup")); const bson_t *doc; mongoc_change_stream_t *change_stream = mongoc_collection_watch (collection, pipeline, opts); while (true) { bson_error_t error; if (mongoc_change_stream_next (change_stream, &doc)) { char *str = bson_as_canonical_extended_json (doc, NULL); printf ("Received change: %s\n", str); bson_free (str); } else if (mongoc_change_stream_error_document (change_stream, &error, NULL)) { printf("Got error on change stream: %s\n", error.message); break; } } bson_destroy (pipeline); bson_destroy (opts); mongoc_change_stream_destroy (change_stream);
With the change stream application running, updating a document in the
restaurants
collection by using the preceding update example prints a change event resembling the following:
{ "_id": ..., "operationType": "update", "clusterTime": ..., "wallTime": ..., "fullDocument": { "_id": { ... }, "address": ..., "borough": "Queens", "cuisine": "Irish", "grades": [ ... ], "name": "Blarney Castle", "restaurant_id": ... }, "ns": { "db": "sample_restaurants", "coll": "restaurants" }, "documentKey": { "_id": ... }, "updateDescription": { "updatedFields": { "cuisine": "Irish" }, "removedFields": [], "truncatedArrays": [] } }
To learn more about pre-images and post-images, see Change Streams with Document Pre- and Post-Images in the MongoDB Server manual.
Additional Information
To learn more about change streams, see Change Streams in the MongoDB Server manual.
API Documentation
To learn more about any of the functions or types discussed in this guide, see the following API documentation: