Docs Menu
Docs Home
/ /
Defina y actualice su modelo de datos

Realizar cambios disruptivos en el esquema

Si necesita realizar cambios en un esquema de objeto utilizado en Atlas Device Sync, puede realizar cambios permanentes sin necesidad de realizar ningún trabajo adicional. Sin embargo, loscambios permanentes requieren pasos adicionales. Un cambio permanente o destructivo incluye cambiar el nombre de un campo existente o cambiar el tipo de datos de un campo.

Para obtener más información,consulte Actualizar su modelo de datos.

Si necesitas realizar un cambio crítico en el esquema, tienes dos opciones:

  • Finalice la sincronización en el backend y luego vuelva a habilitarla desde el principio.

  • Crear una colección de socios, copie los datos antiguos a esta nueva colección y configure activadores para garantizar la coherencia de los datos.

    El resto de esta guía lo guiará en el proceso de creación de una colección de socios.

Advertencia

Restaurar la sincronización después de finalizarla

Al finalizar y reactivar Atlas Device Sync, los clientes ya no podrán sincronizar. Su cliente debe implementar un controlador de restablecimiento de cliente para restaurar la sincronización. Este controlador puede descartar o intentar recuperar los cambios no sincronizados.

En el siguiente procedimiento, la colección inicial utiliza el esquema JSON a continuación para una Task Colección. Tenga en cuenta que el esquema para Task contiene un campo _id de tipo objectId:

Esquema de tareas
{
"title": "Task",
"bsonType": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"_partition": {
"bsonType": "string"
},
"name": {
"bsonType": "string"
}
}
}

El nuevo esquema es el mismo, excepto que queremos que el _id campo sea una cadena:

Esquema de tareas
{
"title": "Task",
"bsonType": "object",
"required": [
"_id",
"name"
],
"properties": {
"_id": {
"bsonType": "string"
},
"_partition": {
"bsonType": "string"
},
"name": {
"bsonType": "string"
}
}
}
1

Dado que no es posible realizar cambios importantes directamente en un esquema de objetos sincronizados, debe crear una colección de socios con un esquema que contenga los cambios necesarios. Debe asegurarse de que la colección de socios contenga los mismos datos que la colección original para que los clientes más nuevos puedan sincronizarse con los antiguos.

El enfoque recomendado para copiar los datos de su colección original a la nueva colección asociada es utilizar el Marco de agregación.

Puede crear y ejecutar una canalización de agregación desde el shell de Mongo, utilizando /aggregation-pipeline-builder/ o con /data-explorer/cloud-agg-pipeline/.

El oleoducto tendrá las siguientes etapas:

  1. Haga coincidir todos los documentos de la colección inicial pasando un filtro vacío al operador $match.

  2. Modifique los campos de la colección inicial mediante un operador de canalización de agregación. En el siguiente ejemplo, los datos se transforman con el operador $addFields. El _id campo se transforma a string tipo con el operador $toString.

  3. Escriba los datos transformados en la colección asociada mediante el operador $out y especificando el nombre de la colección asociada. En este ejemplo, escribimos los datos en una nueva colección TaskV2 llamada.

Aquí se muestra la misma secuencia de comandos que se representa en las interfaces de usuario de Atlas y Compass. Tenga en cuenta que ambas herramientas ofrecen una vista previa de los cambios; en este caso, la conversión del campo _id de un ObjectId a una cadena:

Interfaz de usuario de Atlas para el generador de agregaciones

El siguiente ejemplo muestra la secuencia de agregación completa tal como se vería si utilizara mongosh para realizar la conversión:

Coincidir con todos los documentos en la colección inicial y exportarlos a la colección colaboradora.
use "<database-name>" // switch the current db to the db that the Task collection is stored in
collection = db.Task;
collection.aggregate([
{ $match: {} }, // match all documents in the Task collection
{
$addFields: { // transform the data
_id: { $toString: "$_id" }, // change the _id field of the data to a string type
},
},
{ $out: "TaskV2" }, // output the data to a partner collection, TaskV2
]);
2

Una vez configurada la colección asociada, puede usarla para leer datos existentes. Sin embargo, cualquier nueva escritura en los datos de cualquiera de las colecciones no se realizará en la otra. Esto provoca que los clientes antiguos no estén sincronizados con los nuevos.

Para garantizar que los datos se reflejen en ambas colecciones, se configura un disparador de base de datos en cada una. Cuando se escriben datos en una colección, la función del disparador realiza la escritura en la colección asociada.

Siga los pasos de la documentación del disparador de base de datos para crear un disparador que copie datos de la Task colección a la TaskV2 colección para todos los tipos de operación. Repita estos pasos para crear un segundo disparador que copie datos de la TaskV2 colección a la Task colección.

3

Los activadores requieren funciones de respaldo que se ejecuten cuando el activador se active. En este caso, necesitamos crear dos funciones: una función de migración directa y una función de migración inversa.

El activador de migración directa escucha para inserciones, actualizaciones y eliminaciones en la colección Task, las modifica para reflejar el esquema de la colección TaskV2 y luego las aplica a la colección TaskV2.

Para detectar cambios en la colección TaskV2 y aplicarlos a la colección Task, escriba una función de migración inversa para el disparador de la colección TaskV2. La migración inversa sigue el mismo principio que el paso anterior.

En la función de migración hacia adelante, verificamos qué operación la activó: si el tipo de operación es Delete (lo que significa que se eliminó un documento de la colección Task), este también se elimina de la2 colección TaskV. Si el tipo de operación es Write (insertado o modificado), se crea una canalización de agregación. En la canalización, el documento insertado o modificado de la colección Task se extrae mediante el operador $match. El documento extraído se transforma para que se ajuste al TaskV2 esquema de la colección. Finalmente, los datos transformados se escriben en la TaskV2 colección mediante el operador $merge.

Función copyTaskObjectToTaskV2
exports = function (changeEvent) {
const db = context.services.get("mongodb-atlas").db("ExampleDB");
const collection = db.collection("Task");
// If the event type is "invalidate", the next const throws an error.
// Return early to avoid this.
if (!changeEvent.documentKey) { return; }
// The changed document's _id as an integer:
const changedDocId = changeEvent.documentKey._id;
// If a document in the Task collection has been deleted,
// delete the equivalent object in the TaskV2 collection:
if (changeEvent.operationType === "delete") {
const tasksV2Collection = db.collection("TaskV2");
// Convert the deleted document's _id to a string value
// to match TaskV2's schema:
const deletedDocumentID = changedDocId.toString();
return tasksV2Collection.deleteOne({ _id: deletedDocumentID })
}
// A document in the Task collection has been created,
// modified, or replaced, so create a pipeline to handle the change:
const pipeline = [
// Find the changed document data in the Task collection:
{ $match: { _id: changeEvent.documentKey._id } },
{
// Transform the document by changing the _id field to a string:
$addFields: {
_id: { $toString: "$_id" },
},
},
// Insert the document into TaskV2, using the $merge operator
// to avoid overwriting the existing data in TaskV2:
{ $merge: "TaskV2" }]
return collection.aggregate(pipeline);
};

La función de migración inversa sigue pasos similares a los del ejemplo anterior. Si se elimina un documento en una colección, también se elimina en la otra. Si la operación es de escritura, el documento modificado de TaskV2 se extrae, se transforma para que coincida con el esquema de la colección de tareas y se escribe en la colección Task.

Función copyTaskV2ObjectToTask
exports = function (changeEvent) {
const db = context.services.get("mongodb-atlas").db("ExampleDB");
const collection = db.collection("TaskV2");
// If the event type is "invalidate", the next const throws an error.
// Return early to avoid this.
if (!changeEvent.documentKey) { return; }
// The changed document's _id as a string:
const changedDocId = changeEvent.documentKey._id;
// If a document in the TaskV2 collection has been deleted,
// delete the equivalent object in the Task collection
if (changeEvent.operationType === "delete") {
const taskCollection = db.collection("Task");
// Convert the deleted document's _id to an integer value
// to match Task's schema:
const deletedDocumentID = parseInt(changedDocId);
return taskCollection.deleteOne({ _id: deletedDocumentID })
}
// A document in the Task collection has been created,
// modified, or replaced, so create a pipeline to handle the change:
const pipeline = [
// Find the changed document data in the Task collection
{ $match: { _id: changedDocId } },
{
// Transform the document by changing the _id field
$addFields: {
_id: { $toInt: "$_id" },
},
},
{ $merge: "Task" }
]
return collection.aggregate(pipeline);
};

Se aplica a las aplicaciones de App Services creadas después del 13 de septiembre de 2023.

Servicios de aplicaciones Las aplicaciones en modo de desarrollo que se crearon después del de septiembre 13 de2023 pueden realizar cambios importantes desde su código de cliente a los esquemas de objetos sincronizados.

Consulta el Modo de desarrollo para obtener detalles sobre cómo realizar cambios importantes en el Modo de desarrollo.

El modo de desarrollo no es adecuado para producción. Si lo usa, asegúrese de desactivarlo antes de migrar su aplicación a producción.

Volver

Actualizar un modelo de datos

En esta página