Resumen
updateSe produce un evento
updatecuando una operación actualiza un documento en una colección.Nota
Desambiguación
Para aprender más sobre los eventos que ocurren cuando se modifican las opciones de colección, consulte el
modifyevento.
Descripción
Campo | Tipo | Descripción |
|---|---|---|
| Documento | Un objeto BSON, que actúa como identificador del evento del flujo de cambios. Este valor se utiliza como el parámetro Para obtener un ejemplo de reanudación de un flujo de cambios por |
| Marca de tiempo |
Debido a los límites de tamaño del oplog, las transacciones multidocumentos pueden crear varias entradas de oplog. En una transacción, los eventos de flujo de cambios organizados en una entrada determinada del oplog comparten el mismo Los eventos con el mismo Para identificar eventos para una única transacción, puedes usar la combinación de Cambiado en la versión 8.0. |
| UUID | UUID que identifica la colección en la que se produjo el cambio. Novedades en la versión 6.0. En MongoDB 8.2.0, |
| Documento | Documento que contiene el valor Para los conjuntos particionados, este campo también muestra la clave de partición completa del documento. El campo |
| Documento | El documento creado o modificado mediante una operación CRUD. Este campo solo aparece si configuraste el flujo de cambios con Para obtener más información, consulte Consulta del documento completo para operaciones de actualización. Cambiado en la versión 6.0. A partir de MongoDB 6.0, si configura la opción |
| Documento | El documento antes de que se aplicaran los cambios por la operación. Es decir, la preimagen del documento. Este campo está disponible cuando activas el campo Novedades en la versión 6.0. |
| Documento | El identificador de la sesión asociada con la transacción. Solo aparece si la operación forma parte de una transacción multi-documento. |
| Documento | El namespace (base de datos o colección) afectado por el evento. |
| string | El nombre de la colección donde ocurrió el evento. |
| string | El nombre de la base de datos donde ocurrió el evento. |
| string | El tipo de operación que se reporta en la notificación de cambio. Devuelve un valor de |
| Documento | Un documento que describe los campos que se actualizaron o eliminaron mediante la operación de actualización. |
updateDescription.disambiguatedPaths | Documento | Un documento que proporciona aclaración de descriptores de campos ambiguos en Cuando el evento de cambio de Requiere que configure la opción showExpandedEvents en Nuevo en la versión 6.1. En MongoDB 8.2.0, |
updateDescription.removedFields | arreglo | Un arreglo de campos que fueron eliminados por la operación de actualización. |
updateDescription.truncatedArrays | arreglo | Un conjunto de documentos que registran las truncaciones de matrices realizadas con actualizaciones basadas en pipeline utilizando una o más de las siguientes etapas: Si se reemplaza todo el arreglo, los truncamientos se informarán en updateDescription.updatedFields. |
updateDescription.truncatedArrays.field | string | El nombre del campo truncado. |
updateDescription.truncatedArrays.newSize | entero | El número de elementos en el arreglo truncado. |
updateDescription.updatedFields | Documento | Un documento cuyas claves corresponden a los campos que se modificaron mediante la operación de actualización. El valor de cada campo corresponde al nuevo valor de esos campos, no a la operación que resultó en el nuevo valor. |
| NumberLong | Junto con el lsid, un número que ayuda a identificar de forma única una transacción. Solo aparece si la operación forma parte de una transacción multi-documento. |
| La fecha y hora del servidor de la operación de la base de datos. Novedades en la versión 6.0. |
Comportamiento
Imágenes previas y posteriores al documento
A partir de MongoDB 6.0, verás un documento fullDocumentBeforeChange con los campos que tenía el documento antes de ser cambiado (o eliminado) si realizas los siguientes pasos:
Habilite el nuevo campo
changeStreamPreAndPostImagespara una colección usandodb.createCollection(),create, ocollMod.Configura
fullDocumentBeforeChangeen"required"o"whenAvailable"endb.collection.watch().
Ejemplo fullDocumentBeforeChange documento en la salida del flujo de cambios:
"fullDocumentBeforeChange" : { "_id" : ObjectId("599af247bb69cd89961c986d"), "userName" : "alice123", "name" : "Alice Smith" }
Para obtener ejemplos completos con la salida del flujo de cambios, consulta Flujos de cambio con imágenes previas y posteriores de documentos.
Las imágenes previas y posteriores no están disponibles para un evento de flujo de cambios si las imágenes fueron:
No está habilitado en la colección en el momento de la operación de actualización o eliminación de un documento.
Eliminado después del tiempo de retención de imágenes previas y posteriores establecido en
expireAfterSeconds.El siguiente ejemplo configura
expireAfterSecondsen100segundos en todo el clúster:use admin db.runCommand( { setClusterParameter: { changeStreamOptions: { preAndPostImages: { expireAfterSeconds: 100 } } } } ) Nota
El comando
setClusterParameterno es compatible en los clústeres de MongoDB Atlas. Para obtener información sobre el soporte de Atlas para todos los comandos, consulta Comandos no admitidos en Atlas.El siguiente ejemplo devuelve la configuración actual de
changeStreamOptions, incluyendoexpireAfterSeconds:db.adminCommand( { getClusterParameter: "changeStreamOptions" } ) Configurar
expireAfterSecondsenoffutiliza la política de retención por defecto: las imágenes previas y posteriores se conservan hasta que los eventos correspondientes del flujo de cambios se eliminan del oplog.Si se elimina un evento de flujo de cambios del oplog, las imágenes previas y posteriores correspondientes también se eliminan independientemente del tiempo de retención de las imágenes previas y posteriores
expireAfterSeconds.
Consideraciones adicionales:
Habilitar las imágenes previas y posteriores consume espacio de almacenamiento y aumenta el tiempo de procesamiento. Habilita solo las imágenes previas y de publicación si las necesitas.
Limita el tamaño del evento del flujo de cambios a menos de 16 mebibytes. Para limitar el tamaño del evento, puedes:
Limita el tamaño del documento a 8 megabytes. Puedes solicitar imágenes previas y posteriores simultáneamente en la salida del flujo de cambios si otros campos de eventos del flujo de cambios como
updateDescriptionno son grandes.Solicita solo imágenes posteriores en la salida del flujo de cambios para documentos de hasta 16 mebibytes si otros campos de eventos del flujo de cambios como
updateDescriptionno son grandes.Solicita solo imágenes previas en la salida del flujo de cambios para documentos de hasta 16 mebibytes si:
las actualizaciones de documento afectan solo a una pequeña fracción de la estructura o el contenido del documento, y
no cause un evento de cambio
replace. Un eventoreplacesiempre incluye la imagen de publicación.
Para realizar una solicitud de imagen previa, debes establecer
fullDocumentBeforeChangeenrequiredowhenAvailableendb.collection.watch(). Para solicitar una imagen posterior, establecefullDocumentmediante el mismo método.Las imágenes previas se escriben en la colección
config.system.preimages.La colección
config.system.preimagespuede agrandarse. Para limitar el tamaño de la colección, puedes establecer el tiempo aexpireAfterSecondspara las imágenes previas como se mostró antes.Para supervisar el tamaño de
config.system.preimages, conecta a un nodo de partición en un clúster o a un nodomongoden un set de réplicas. A continuación, ejecuta los siguientes comandos:use config db.system.preimages.totalSize() db.system.preimages.stats() Las imágenes previas se eliminan de forma asincrónica mediante un proceso en segundo plano.
Importante
Característica incompatible con versiones anteriores
A partir de MongoDB 6.0, si utilizas imágenes previas y posteriores de documentos para los flujos de cambios, debes deshabilitar changeStreamPreAndPostImages para cada colección mediante el comando collMod antes de poder volver a una versión anterior de MongoDB.
Tip
Para los eventos y resultados del flujo de cambios, consulta Eventos de cambio.
Para buscar cambios en una colección, consulta
db.collection.watch().Para obtener ejemplos completos con la salida del flujo de cambios, consulta Flujos de cambio con imágenes previas y posteriores de documentos.
Desambiguación de ruta
Nuevo en la versión 6.1.
El campo updateDescription anota los cambios realizados en campos específicos de los documentos mediante una operación. Estos descriptores de campo utilizan puntos (.) como separadores de ruta y números como índices de arreglo, lo que conduce a cierta ambigüedad cuando contienen nombres de campo que utilizan puntos o números.
Cuando un evento update informa cambios que involucran campos ambiguos, el documento disambiguatedPaths proporciona la clave de ruta con un arreglo que lista cada componente de la ruta.
Nota
El campo disambiguatedPaths está disponible para flujos de cambios que incluyen eventos ampliados.
En MongoDB 8.2.0, collectionUUID y updateDescription.disambiguatedPaths están incluidos en los eventos de cambio aplicables incluso si no configuras showExpandedEvents. En las versiones de MongoDB anteriores a 8.2.0 y en las versiones 8.2.1 y posteriormente, estos campos se incluyen únicamente si abres el flujo de cambios con showExpandedEvents: true.
Por ejemplo, considera un documento que enumera a las personas y las ciudades en las que viven:
{ "name": "Anthony Trollope", "home.town": "Oxford", "residences": [ {"0": "Oxford"}, {"1": "Sunbury"} ] }
Cuando una actualización modifica el campo
home.towndeOxfordaLondon, produce una descripción de actualización que se ve así:"updateDescription": { "updatedFields": { "home.town": "London" }, "disambiguatedPaths": { "home.town": [ "home.town" ] } } Debido a que el campo
home.towncontiene un punto, el campodisambiguatedPathsmuestra un arreglo con un único valor, para indicar quetownno es un subcampo dehome.Cuando una actualización modifica un valor en el arreglo
residencespara realizar el mismo cambio, se produce una descripción de actualización que se ve así:"updateDescription": { "updatedFields": { "residences.0.0": "London" }, "disambiguatedPaths": { "residences.0.0": [ "residences", 0, "0" ] } } Los caminos desambiguados incluyen un entero
0para indicar el índice del arreglo y la cadena"0"para indicar el nombre del campo dentro del documento anidado.
Hay dos casos en los que disambiguatedPath no incluye un campo numérico:
Cuando el primer campo en la ruta es una string numérica (es decir,
0.name). Esto no es ambiguo, ya que el primer campo no puede ser un índice de arreglo.Cuando el campo de string numérica tiene ceros a la izquierda (es decir,
0001). Esto no es ambiguo, ya que un entero no puede tener ceros a la izquierda.
Operaciones de actualizar
El comando update puede producir diferentes eventos de cambio (no solo update) dependiendo de los cambios reales que realiza en la colección.
Evento de cambio | Descripción |
|---|---|
La operación de actualización modificó un documento existente. | |
La operación de actualización reemplazó el documento o produjo una diferencia que era más extensa que el documento original, haciendo que MongoDB lo reemplazara. | |
La operación de actualización intentó actualizar un documento que no existe y, en su lugar, agregó el documento a la colección. Esto solo ocurre cuando la actualización se ejecuta con la opción |
Comparación de actualizaciones estándar y actualizaciones por pipeline
En algunos escenarios, las actualizaciones estándar y las actualizaciones del pipeline pueden generar diferentes eventos de cambio para el mismo cambio lógico. Si cambias entre la sintaxis estándar y la de actualización de pipeline, puede que observes eventos de cambio inesperados en tu aplicación.
El siguiente ejemplo muestra cómo las diferentes sintaxis de actualización producen diferentes eventos de cambio al remover subcampos de documentos incrustados. Este es solo uno de los muchos escenarios en los que los eventos de cambio difieren según la sintaxis de actualización utilizada.
Actualizaciones estándar: Cuando se eliminan subcampos de un objeto incrustado, las rutas eliminadas siempre están en el arreglo
removedFields.Pipeline Updates: Cuando se eliminan subcampos de un objeto incrustado, el evento de cambio resultante muestra la descripción más concisa de la actualización. Por ejemplo:
Si se eliminan una pequeña cantidad de subcampos (por ejemplo, removiendo 1 de 3 subcampos), el cambio se muestra en el arreglo
removedFields.Si se remueven la mayoría de los subcampos (por ejemplo, eliminar 2 de 3 subcampos), el cambio se muestra en el arreglo
updatedFieldsy el objeto principal refleja el nuevo estado.
El siguiente script de ejemplo muestra los diferentes eventos de cambio generados por actualizaciones estándar y actualizaciones de pipeline que remueven subcampos de un objeto:
// 1. Setup collection and insert documents for test cases let contactMethods = { email: "user@example.com", phone: "555-0100", mobile: "555-0101" }; db.cstest.drop(); db.cstest.insertMany([ // Case 1: Remove 1 of 3 subfields { _id: "standard_remove_1_of_3", contactMethods: contactMethods }, { _id: "pipeline_remove_1_of_3", contactMethods: contactMethods }, // Case 2: Remove 2 of 3 subfields { _id: "standard_remove_2_of_3", contactMethods: contactMethods }, { _id: "pipeline_remove_2_of_3", contactMethods: contactMethods } ]); // 2. Open a Change Stream const csCursor = db.cstest.watch(); // --- CASE 1: Remove 1 out of 3 subfields --- db.cstest.updateOne({ _id: "standard_remove_1_of_3" }, { $unset: { "contactMethods.email": "" } }); db.cstest.updateOne({ _id: "pipeline_remove_1_of_3" }, [{ $unset: "contactMethods.email" }]); // --- CASE 2: Remove 2 out of 3 subfields --- db.cstest.updateOne({ _id: "standard_remove_2_of_3" }, { $unset: { "contactMethods.email": "", "contactMethods.phone": "" } }); db.cstest.updateOne({ _id: "pipeline_remove_2_of_3" }, [{ $unset: ["contactMethods.email", "contactMethods.phone"] }]); // 3. Print the change stream updateDescriptions print("\n--- Change Stream Results ---"); for (let i = 0; i < 4; i++) { if (csCursor.hasNext()) { let event = csCursor.next(); print(`\nOperation: ${event.documentKey._id}`); print(JSON.stringify(event.updateDescription)); } } csCursor.close();
--- Change Stream Results --- Operation: standard_remove_1_of_3 {"updatedFields":{},"removedFields":["contactMethods.email"],"truncatedArrays":[]} Operation: pipeline_remove_1_of_3 {"updatedFields":{},"removedFields":["contactMethods.email"],"truncatedArrays":[]} Operation: standard_remove_2_of_3 {"updatedFields":{},"removedFields":["contactMethods.email","contactMethods.phone"],"truncatedArrays":[]} Operation: pipeline_remove_2_of_3 {"updatedFields":{"contactMethods":{"mobile":"555-0101"}},"removedFields":[],"truncatedArrays":[]}
Array Updates
Las actualizaciones en los arreglos producen eventos de cambio update, pero el updateDescription.updateFields puede mostrar diferentes valores.
Por ejemplo, considera el siguiente documento y las actualizaciones:
db.students.insertOne( { student_id: 1, scores: [ ] } ) db.students.updateOne( { student_id: 1 }, { $push: { scores: 0.85 } } ) db.students.updateOne( { student_id: 1 }, { $push: { scores: 0.94 } } ) db.students.updateOne( { student_id: 1 }, { $pull: { scores: 0.94 } } )
La primera actualización opera sobre un arreglo vacío. Aquí, $push produce un evento de cambio update en el cual el campo es reemplazado por un arreglo de una sola entrada con el valor dado:
{ _id: { _data: '82642AD66B000000012B022C0100296E5A10045DC4B11BEA5F4319A8E7CAF46816ED71461E5F6964002B060004' }, operationType: 'update', clusterTime: Timestamp({ t: 1680529003, i: 1 }), ns: { db: 'communication_chat', coll: 'students' }, documentKey: { student_id: 1 }, updateDescription: { updatedFields: { scores: [ 0.85 ] }, removedFields: [], truncatedArrays: [] } }
En la segunda operación de actualización, el arreglo ahora contiene valores. El $push añade una nueva entrada en el arreglo. El evento de cambio update lo muestra como un cambio en la nueva posición del arreglo (es decir, scores.1):
{ _id: { _data: '82642AD673000000012B022C0100296E5A10045DC4B11BEA5F4319A8E7CAF46816ED71461E5F6964002B060004' }, operationType: 'update', clusterTime: Timestamp({ t: 1680529011, i: 1 }), ns: { db: 'communication_chat', coll: 'students' }, documentKey: { student_id: 1 }, updateDescription: { updatedFields: { 'scores.1': 0.94 }, removedFields: [], truncatedArrays: [] } }
Si ejecutas la operación de actualización de nuevo para añadir una tercera puntuación al registro del estudiante, se produciría un evento de cambio update que modifica scores.2.
La eliminación de elementos de arreglo con el operador $pull produce un evento de cambio que muestra el nuevo arreglo:
{ _id: { _data: '82642AD673000000012B022C0100296E5A10045DC4B11BEA5F4319A8E7CAF46816ED71461E5F6964002B060004' }, operationType: 'update', clusterTime: Timestamp({ t: 1680529011, i: 1 }), ns: { db: 'communication_chat', coll: 'students' }, documentKey: { student_id: 1 }, updateDescription: { updatedFields: { scores: [ 0.85 ] }, removedFields: [], truncatedArrays: [] } }
Truncamiento de arreglo
Las operaciones de actualización que reducen el número de elementos en los arreglos mediante las actualizaciones por etapas (pipeline), como en las etapas de agregación $addFields o $set, muestran el arreglo actualizado y el nuevo tamaño en el campo truncatedArrays.
db.students.insertOne( { student_id: 2, scores: [ 0.85, 0.94, 0.78 ] } ) db.students.updateOne( { student_id: 2 }, [ { $addFields: { scores: [ 0.85, 0.94 ] } } ] ) db.students.updateOne( { student_id: 2 }, [ { $addFields: { scores: [ 0.85, 0.94, 0.78 ] } } ] )
El evento de cambio de la primera actualización, que utilizó la etapa $addFields para remover un valor del campo scores muestra el cambio en el campo truncatedArrays:
{ _id: { _data: '82642AD673000000012B022C0100296E5A10045DC4B11BEA5F4319A8E7CAF46816ED71461E5F6964002B060004' }, operationType: 'update', clusterTime: Timestamp({ t: 1680529011, i: 1 }), ns: { db: 'communication_chat', coll: 'students' }, documentKey: { student_id: 2 }, updateDescription: { updatedFields: {}, removedFields: [], truncatedArrays: [ { fields: "scores", newSize: 2 } ] } }
El evento de cambio de la segunda actualización, que usó la etapa $addFields para agregar un valor de vuelta al campo scores, muestra la actualización en el campo updatedFields:
{ _id: { _data: '82642AD673000000012B022C0100296E5A10045DC4B11BEA5F4319A8E7CAF46816ED71461E5F6964002B060004' }, operationType: 'update', clusterTime: Timestamp({ t: 1680529011, i: 1 }), ns: { db: 'communication_chat', coll: 'students' }, documentKey: { student_id: 2 }, updateDescription: { updatedFields: { scores.2: 0.78 }, removedFields: [], truncatedArrays: [] } }
Ejemplo
El siguiente ejemplo ilustra un evento update:
{ "_id": { <Resume Token> }, "operationType": "update", "clusterTime": <Timestamp>, "wallTime": <ISODate>, "ns": { "db": "engineering", "coll": "users" }, "documentKey": { "_id": ObjectId("58a4eb4a30c75625e00d2820") }, "updateDescription": { "updatedFields": { "email": "alice@10gen.com" }, "removedFields": ["phoneNumber"], "truncatedArrays": [ { "field" : "vacation_time", "newSize" : 36 } ] } }
El siguiente ejemplo ilustra un evento update para flujos de cambios abiertos con la opción fullDocument : updateLookup:
{ "_id": { <Resume Token> }, "operationType": "update", "clusterTime": <Timestamp>, "wallTime": <ISODate>, "ns": { "db": "engineering", "coll": "users" }, "documentKey": { "_id": ObjectId("58a4eb4a30c75625e00d2820") }, "updateDescription": { "updatedFields": { "email": "alice@10gen.com" }, "removedFields": ["phoneNumber"], "truncatedArrays": [ { "field" : "vacation_time", "newSize" : 36 } ], "disambiguatedPaths": { } }, "fullDocument": { "_id": ObjectId("58a4eb4a30c75625e00d2820"), "name": "Alice", "userName": "alice123", "email": "alice@10gen.com", "team": "replication" } }
El documento fullDocument representa la versión más actual comprometida por mayoría del documento actualizado. El documento fullDocument puede variar del documento en el momento de la operación de actualización, dependiendo de la cantidad de operaciones intercaladas comprometidas por mayoría que ocurran entre la operación de actualización y la búsqueda del documento.