Overview
En esta guía, puedes aprender a utilizar un flujo de cambios para supervisar los cambios en tiempo real de tu base de datos. Un flujo de cambios es una funcionalidad de MongoDB Server que permite que la aplicación se suscriba a cambios en los datos de una colección, base de datos o implementación.
Tip
Atlas Stream Processing
Como alternativa a los flujos de cambios, puedes usar Atlas Stream Processing para procesar y transformar flujos de datos. A diferencia de los flujos de cambios, que solo registran eventos de base de datos, Atlas Stream Processing administra múltiples tipos de eventos de datos y ofrece capacidades avanzadas de procesamiento de datos. Para obtener más información sobre esta funcionalidad, consulta Atlas Stream Processing en la documentación de MongoDB Atlas.
Datos de muestra
Los ejemplos en esta guía utilizan la colección sample_restaurants.restaurants de los conjuntos de datos de muestra de Atlas. Para aprender cómo crear un clúster gratuito de MongoDB Atlas y cargar los conjuntos de datos de muestra, consulta Comenzar con PyMongo.
Abre un flujo de cambios
Para abrir un flujo de cambios, llama al método watch(). La instancia en la que se llama al método watch() determina el alcance de los eventos para los que el flujo de cambios escucha. Puedes llamar al método watch() en las siguientes clases:
MongoClient: Para supervisar todos los cambios en la implementación de MongoDBDatabase: Para supervisar los cambios en todas las colecciones de la base de datosCollection: Para supervisar los cambios en la colección
El siguiente ejemplo abre un flujo de cambios en la colección restaurants y muestra los cambios a medida que ocurren. Selecciona la pestaña Synchronous o Asynchronous para ver el código correspondiente:
database = client["sample_restaurants"] collection = database["restaurants"] with collection.watch() as stream: for change in stream: print(change)
database = client["sample_restaurants"] collection = database["restaurants"] async with await collection.watch() as stream: async for change in stream: print(change)
Para comenzar a observar los cambios, ejecuta la aplicación. Luego, en una aplicación o shell aparte, modifica la colección restaurants. El siguiente ejemplo actualiza un documento con un valor de campo name de Blarney Castle. Selecciona la pestaña Synchronous o Asynchronous para ver el código correspondiente:
database = client["sample_restaurants"] collection = database["restaurants"] query_filter = { "name": "Blarney Castle" } update_operation = { '$set' : { "cuisine": "Irish" } } result = collection.update_one(query_filter, update_operation)
database = client["sample_restaurants"] collection = database["restaurants"] query_filter = { "name": "Blarney Castle" } update_operation = { '$set' : { "cuisine": "Irish" } } result = await collection.update_one(query_filter, update_operation)
Cuando actualizas la colección, la aplicación del flujo de cambios imprime el cambio a medida que ocurre. El evento de cambio impreso se parece al siguiente:
{'_id': {'_data': '...'}, 'operationType': 'update', 'clusterTime': Timestamp(...), 'wallTime': datetime.datetime(...), 'ns': {'db': 'sample_restaurants', 'coll': 'restaurants'}, 'documentKey': {'_id': ObjectId('...')}, 'updateDescription': {'updatedFields': {'cuisine': 'Irish'}, 'removedFields': [], 'truncatedArrays': []}}
Modificar la Salida del Cambio de Flujo
Puedes pasar el parámetro pipeline al método watch() para modificar la salida del flujo de cambios. Este parámetro te permite monitorear solo los eventos de cambio especificados. Da formato al parámetro como una lista de objetos que representen cada uno una etapa de agregación.
Puede especificar las siguientes etapas en el parámetro pipeline:
$addFields$match$project$replaceRoot$replaceWith$redact$set$unset
El siguiente ejemplo utiliza el parámetro pipeline para abrir un flujo de cambios que registra solo las operaciones de actualización. Seleccione la pestaña Synchronous o Asynchronous para ver el código correspondiente:
change_pipeline = { "$match": { "operationType": "update" }}, with collection.watch(pipeline=change_pipeline) as stream: for change in stream: print(change)
change_pipeline = { "$match": { "operationType": "update" }}, async with await collection.watch(pipeline=change_pipeline) as stream: async for change in stream: print(change)
Para obtener más información sobre cómo modificar la salida de tu flujo de cambios, consulta la sección Modificar salida del flujo de cambio en el manual del MongoDB Server.
Modificar el comportamiento de watch()
El método watch() acepta parámetros opcionales, que representan opciones que puedes usar para configurar la operación. Si no especificas ninguna opción, el driver no personaliza la operación.
La siguiente tabla describe las opciones que puedes configurar para personalizar el comportamiento de watch():
Propiedad | Descripción |
|---|---|
| Una lista de etapas del pipeline de agregación que modifican el resultado del flujo de cambios. |
| Especifica si se debe mostrar el documento completo después del cambio, en lugar de mostrar solo los cambios realizados en el documento. Para aprender más sobre esta opción, consulta Incluir preimágenes y posimágenes. |
| Especifica si se debe mostrar el documento completo tal como estaba antes del cambio, en lugar de mostrar solo las modificaciones realizadas en el documento. Para obtener más información sobre esta opción, consulte Incluir imágenes previas y posteriores. |
| Indica |
| Indica a |
| Indica |
| La cantidad máxima de tiempo, en milisegundos, que el servidor espera para informar cambios nuevos de datos al cursor del flujo de cambios antes de retornar un agrupar vacío. Por defecto, 1000 milisegundos. |
| A partir de MongoDB Server v6.0, los flujos de cambios admiten notificaciones de cambios para eventos de Data Definition lenguaje (DDL), como los eventos |
| El número máximo de eventos de cambio a devolver en cada agrupar de la respuesta del clúster de MongoDB. |
| La intercalación que se utilizará para el cursor del flujo de cambios. |
| Una instancia de |
| Un comentario para adjuntar a la operación. |
Incluir imágenes preoperativas y postoperatorias
Importante
Puede habilitar pre imágenes y post imágenes en colecciones solo si su implementación utiliza MongoDB v6.0 o posterior.
De forma predeterminada, cuando realizas una operación en una colección, el evento de cambio correspondiente solo incluye el delta de los campos modificados por esa operación. Para ver el documento completo antes o después de un cambio, especifica los parámetros full_document_before_change o full_document en el método watch().
La preimagen es la versión completa de un documento antes de un cambio. Para incluir la preimagen en el evento de flujo de cambios, establece el parámetro full_document_before_change en uno de los siguientes valores:
whenAvailable: El evento de cambio incluye una preimagen del documento modificado para los eventos de cambio solo si la preimagen está disponible.requiredEl evento de cambio incluye una preimagen del documento modificado para los eventos de cambio. Si la preimagen no está disponible, el driver genera un error.
La post-imagen es la versión completa de un documento después de un cambio. Para incluir la imagen posterior en el evento del flujo de cambios, configure el parámetro full_document con uno de los siguientes valores:
updateLookup: El evento de cambio incluye una copia de todo el documento cambiado a partir de cierto tiempo después del cambio.whenAvailable: El evento de cambio incluye una postimagen del documento modificado para eventos de cambio solo si la postimagen está disponible.required: El evento de cambio incluye una imagen posterior del documento modificado para eventos de cambio. Si la imagen posterior no está disponible, el driver genera un error.
El siguiente ejemplo invoca el método watch() en una colección e incluye las versiones posteriores a la actualización de los documentos al especificar el parámetro fullDocument. Selecciona la pestaña Synchronous o Asynchronous para ver el código correspondiente:
database = client["sample_restaurants"] collection = database["restaurants"] with collection.watch(full_document='updateLookup') as stream: for change in stream: print(change)
database = client["sample_restaurants"] collection = database["restaurants"] async with await collection.watch(full_document='updateLookup') as stream: async for change in stream: print(change)
Con la aplicación de flujo de cambios ejecutándose, actualizar un documento en la colección restaurants usando el ejemplo anterior de actualización imprime un evento de cambio semejante al siguiente:
{'_id': {'_data': '...'}, 'operationType': 'update', 'clusterTime': Timestamp(...), 'wallTime': datetime.datetime(...), 'fullDocument': {'_id': ObjectId('...'), 'address': {...}, 'borough': 'Queens', 'cuisine': 'Irish', 'grades': [...], 'name': 'Blarney Castle', 'restaurant_id': '40366356'}, 'ns': {'db': 'sample_restaurants', 'coll': 'restaurants'}, 'documentKey': {'_id': ObjectId('...')}, 'updateDescription': {'updatedFields': {'cuisine': 'Irish'}, 'removedFields': [], 'truncatedArrays': []}}
Para obtener más información sobre pre-imágenes y post-imágenes, consulta Change Streams con preimágenes y postimágenes de documentos en el manual de MongoDB Server.
Información Adicional
Para saber más sobre las change streams, consulta Change Streams en el manual de MongoDB Server.
Documentación de la API
Para aprender más sobre cualquiera de los métodos o tipos analizados en esta guía, consulta la siguiente documentación de API: