Docs Menu
Docs Home
/ /

Escribir datos en MongoDB Atlas - Funciones

Los ejemplos de esta página demuestran cómo utilizar la API de consulta de MongoDB en una función para insertar, actualizar y eliminar datos en su clúster Atlas.

Nota

Fuentes de datos federadas No admite operaciones de escritura.

Los ejemplos de esta página utilizan una colección denominada store.items Que modela varios artículos disponibles para la compra en una tienda en línea. Cada artículo tiene un name, un inventario quantity y una matriz de clientes reviews.

El esquema JSON para store.items
{
"title": "Item",
"required": ["_id", "name", "quantity", "reviews"],
"properties": {
"_id": { "bsonType": "objectId" },
"name": { "bsonType": "string" },
"quantity": { "bsonType": "int" },
"reviews": {
"bsonType": "array",
"items": {
"bsonType": "object",
"required": ["username", "comment"],
"properties": {
"username": { "bsonType": "string" },
"comment": { "bsonType": "string" }
}
}
}
}
}

Para utilizar un fragmento de código en una función, primero debe crear una instancia de un controlador de colección de MongoDB:

exports = function() {
const mongodb = context.services.get("mongodb-atlas");
const itemsCollection = mongodb.db("store").collection("items");
const purchasesCollection = mongodb.db("store").collection("purchases");
// ... paste snippet here ...
}

Las operaciones de inserción toman uno o más documentos y los añaden a una colección de MongoDB.

Devuelven documentos que describen los resultados de la operación.

Puede insertar un solo documento utilizando el collection.insertOne() método.

El siguiente Function snippet inserta un documento de elemento único en la colección items:

const newItem = {
"name": "Plastic Bricks",
"quantity": 10,
"category": "toys",
"reviews": [{ "username": "legolover", "comment": "These are awesome!" }]
};
itemsCollection.insertOne(newItem)
.then(result => console.log(`Successfully inserted item with _id: ${result.insertedId}`))
.catch(err => console.error(`Failed to insert item: ${err}`))

Puede insertar varios documentos al mismo tiempo utilizando el collection.insertMany() método.

El siguiente fragmento de función inserta varios documentos de elementos en la items colección:

const doc1 = { "name": "basketball", "category": "sports", "quantity": 20, "reviews": [] };
const doc2 = { "name": "football", "category": "sports", "quantity": 30, "reviews": [] };
return itemsCollection.insertMany([doc1, doc2])
.then(result => {
console.log(`Successfully inserted ${result.insertedIds.length} items!`);
return result
})
.catch(err => console.error(`Failed to insert documents: ${err}`))

Las operaciones de actualización buscan documentos existentes en una colección de MongoDB y modifican sus datos. Se utiliza la sintaxis de consulta estándar de MongoDB para especificar qué documentos actualizar y... operadores de actualización para describir los cambios que se aplicarán a los documentos coincidentes.

Al ejecutar operaciones de actualización, las Funciones Atlas añaden temporalmente un campo reservado, _id__baas_transaction, a los documentos. Una vez que un documento se actualiza correctamente, las Funciones Atlas eliminan este campo.

Si desea utilizar otra herramienta para modificar datos en una colección, asegúrese de deshabilitar este campo antes de realizar cambios.

Por ejemplo, si está utilizando el shell mongosh para actualizar documentos en la colección de productos, su comando podría parecerse al siguiente código:

db.products.update(
{ sku: "unknown" },
{ $unset: { _id__baas_transaction: "" } }
)

Puede actualizar un solo documento utilizando el collection.updateOne() método.

El siguiente fragmento de función actualiza el name de un solo documento en la items colección de lego a blocks y agrega un price 20.99de:

const query = { "name": "lego" };
const update = {
"$set": {
"name": "blocks",
"price": 20.99,
"category": "toys"
}
};
const options = { "upsert": false };
itemsCollection.updateOne(query, update, options)
.then(result => {
const { matchedCount, modifiedCount } = result;
if(matchedCount && modifiedCount) {
console.log(`Successfully updated the item.`)
}
})
.catch(err => console.error(`Failed to update the item: ${err}`))

Como alternativa, puede actualizar un solo documento usando o. Ambos métodos permiten buscar, modificar y devolver el documento actualizado en una sola collection.findOneAndUpdate() collection.findOneAndReplace()operación.

Puede actualizar varios documentos en una colección utilizando el collection.updateMany() método.

El siguiente fragmento de función actualiza todos los documentos de la items colección multiplicando sus quantity valores 10 por:

const query = {};
const update = { "$mul": { "quantity": 10 } };
const options = { "upsert": false }
return itemsCollection.updateMany(query, update, options)
.then(result => {
const { matchedCount, modifiedCount } = result;
console.log(`Successfully matched ${matchedCount} and modified ${modifiedCount} items.`)
return result
})
.catch(err => console.error(`Failed to update items: ${err}`))

Si una operación de actualización no coincide con ningún documento de la colección, puede insertar automáticamente un solo documento nuevo en la colección que coincida con la consulta de actualización configurando la opción upsert en true.

El siguiente fragmento de función actualiza un documento de la items colección name board game cuyo quantity valor es incrementando su valor 5 en. La upsert opción está habilitada, por lo que si ningún documento tiene un name valor igual a,"board game" MongoDB inserta un nuevo documento con el name campo establecido en "board game" y el quantity valor establecido 5 en:

const query = { "name": "board games" };
const update = { "$inc": { "quantity": 5 } };
const options = { "upsert": true };
itemsCollection.updateOne(query, update, options)
.then(result => {
const { matchedCount, modifiedCount, upsertedId } = result;
if(upsertedId) {
console.log(`Document not found. Inserted a new document with _id: ${upsertedId}`)
} else {
console.log(`Successfully increased ${query.name} quantity by ${update.$inc.quantity}`)
}
})
.catch(err => console.error(`Failed to upsert document: ${err}`))

Los operadores de campo le permiten modificar los campos y valores de un documento.

Puede utilizar el operador $set para establecer el valor de un solo campo sin afectar otros campos de un documento.

{ "$set": { "<Field Name>": <Value>, ... } }

Puede utilizar el operador $rename para cambiar el nombre de un solo campo en un documento.

{ "$rename": { "<Current Field Name>": <New Field Name>, ... } }

Puede usar el operador $inc para sumar un número específico al valor actual de un campo. El número puede ser positivo o negativo.

{ "$inc": { "<Field Name>": <Increment Number>, ... } }

Puedes usar el operador $mul para multiplicar un número específico por el valor actual de un campo. El número puede ser positivo o negativo.

{ "$mul": { "<Field Name>": <Multiple Number>, ... } }

Los operadores de matriz le permiten trabajar con valores dentro de matrices.

Puede utilizar el operador $push para agregar un valor al final de un campo de matriz.

{ "$push": { "<Array Field Name>": <New Array Element>, ... } }

Puede usar el operador $pop para eliminar el primer o el último elemento de un campo de matriz. Especifique -1 para eliminar el primer elemento y 1 para eliminar el último.

{ "$pop": { "<Array Field Name>": <-1 | 1>, ... } }

Puede usar el operador $addToSet para agregar un valor a un campo de matriz si dicho valor aún no está incluido en la matriz. Si el valor ya está presente, $addToSet no hace nada.

{ "$addToSet": { "<Array Field Name>": <Potentially Unique Value>, ... } }

Puede utilizar el operador $pull para eliminar todas las instancias de cualquier valor que coincida con una condición especificada de un campo de matriz.

{ "$pull": { "<Array Field Name>": <Value | Expression>, ... } }

Puede utilizar el operador $[] (Actualización de todas las posiciones) para actualizar todos los elementos en un campo de matriz:

Ejemplo

Considere una colección students que describe a los estudiantes de una clase. Cada documento incluye un campo grades que contiene una matriz de números:

{ "_id" : 1, "grades" : [ 85, 82, 80 ] }
{ "_id" : 2, "grades" : [ 88, 90, 92 ] }
{ "_id" : 3, "grades" : [ 85, 100, 90 ] }

La siguiente operación de actualización agrega 10 a todos los valores en la matriz grades de cada estudiante:

await students.updateMany(
{},
{ $inc: { "grades.$[]": 10 } },
)

Después de la actualización, cada valor de calificación aumentó en 10:

{ "_id" : 1, "grades" : [ 95, 92, 90 ] }
{ "_id" : 2, "grades" : [ 98, 100, 102 ] }
{ "_id" : 3, "grades" : [ 95, 110, 100 ] }

Puede utilizar el operador $[element] (Actualización posicional filtrada) para actualizar elementos específicos en un campo de matriz según un filtro de matriz:

Ejemplo

Considere una colección students que describe a estudiantes individuales de una clase. Cada documento incluye un campo grades que contiene una matriz de números, algunos de los cuales son mayores que 100:

{ "_id" : 1, "grades" : [ 15, 92, 90 ] }
{ "_id" : 2, "grades" : [ 18, 100, 102 ] }
{ "_id" : 3, "grades" : [ 15, 110, 100 ] }

La siguiente operación de actualización establece todos los valores de calificación superiores a 100 exactamente en 100:

await students.updateMany(
{ },
{
$set: {
"grades.$[grade]" : 100
}
},
{
arrayFilters: [{ "grade": { $gt: 100 } }]
}
)

Después de la actualización, todos los valores de calificación mayores a 100 se establecen exactamente en 100 y todas las demás calificaciones no se ven afectadas:

{ "_id" : 1, "grades" : [ 15, 92, 90 ] }
{ "_id" : 2, "grades" : [ 18, 100, 100 ] }
{ "_id" : 3, "grades" : [ 15, 100, 100 ] }

Las operaciones de eliminación buscan documentos existentes en una colección de MongoDB y los eliminan. Se utiliza la sintaxis de consulta estándar de MongoDB para especificar qué documentos eliminar.

Puede eliminar un solo documento de una colección utilizando el collection.deleteOne() método.

El siguiente fragmento de función elimina un documento en la items colección que tiene un name valor lego de:

const query = { "name": "lego" };
itemsCollection.deleteOne(query)
.then(result => console.log(`Deleted ${result.deletedCount} item.`))
.catch(err => console.error(`Delete failed with error: ${err}`))

Como alternativa, puede actualizar un solo documento usando. Este método le permite buscar, eliminar y recuperar el documento eliminado en una sola collection.findOneAndDelete() operación.

Puede eliminar varios elementos de una colección utilizando el collection.deleteMany() método.

El siguiente fragmento elimina todos los documentos de la colección items que no tienen ningún reviews:

const query = { "reviews": { "$size": 0 } };
itemsCollection.deleteMany(query)
.then(result => console.log(`Deleted ${result.deletedCount} item(s).`))
.catch(err => console.error(`Delete failed with error: ${err}`))

Una escritura masiva combina varias operaciones de escritura en una sola. Puede ejecutar un comando de escritura masiva con el collection.bulkWrite() método.

exports = async function(arg){
const doc1 = { "name": "velvet elvis", "quantity": 20, "reviews": [] };
const doc2 = { "name": "mock turtleneck", "quantity": 30, "reviews": [] };
var collection = context.services.get("mongodb-atlas")
.db("store")
.collection("purchases");
return await collection.bulkWrite(
[{ insertOne: doc1}, { insertOne: doc2}],
{ordered:true});
};

MongoDB admite transacciones de múltiples documentos que le permiten leer y escribir múltiples documentos de forma atómica, incluso en colecciones.

Para realizar una transacción:

  1. Obtenga y comience una sesión de cliente con client.startSession().

  2. Llama a session.withTransaction() para definir la transacción. El método utiliza una función de devolución de llamada asíncrona y, opcionalmente, un objeto de configuración que define ajustes personalizados de lectura y escritura para la transacción.

    session.withTransaction(async () => {
    // ... Run MongoDB operations in this callback
    }, {
    readPreference: "primary",
    readConcern: { level: "local" },
    writeConcern: { w: "majority" },
    })
  3. En la función de devolución de llamada de transacción, ejecute las consultas de MongoDB que desee incluir en la transacción. Asegúrese de pasar el valor session a cada consulta para garantizar que se incluya en la transacción.

    await accounts.updateOne(
    { name: userSubtractPoints },
    { $inc: { browniePoints: -1 * pointVolume } },
    { session }
    );
  4. Si la devolución de llamada detecta un error, se llama a session.abortTransaction() para detener la transacción. Una transacción cancelada no modifica ningún dato.

    try {
    // ...
    } catch (err) {
    await session.abortTransaction();
    }
  5. Cuando se complete la transacción, llame a session.endSession() para finalizar la sesión y liberar recursos.

    try {
    // ...
    } finally {
    await session.endSession();
    }

El siguiente ejemplo crea dos usuarios, "henry" y "michelle", y utiliza una transacción para transferir "browniePoints" entre esos usuarios atómicamente:

exports = function () {
const client = context.services.get("mongodb-atlas");
db = client.db("exampleDatabase");
accounts = db.collection("accounts");
browniePointsTrades = db.collection("browniePointsTrades");
// create user accounts with initial balances
accounts.insertOne({ name: "henry", browniePoints: 42 });
accounts.insertOne({ name: "michelle", browniePoints: 144 });
// trade points between user accounts in a transaction
tradeBrowniePoints(
client,
accounts,
browniePointsTrades,
"michelle",
"henry",
5
);
return "Successfully traded brownie points.";
};
async function tradeBrowniePoints(
client,
accounts,
browniePointsTrades,
userAddPoints,
userSubtractPoints,
pointVolume
) {
// Step 1: Start a Client Session
const session = client.startSession();
// Step 2: Optional. Define options to use for the transaction
const transactionOptions = {
readPreference: "primary",
readConcern: { level: "local" },
writeConcern: { w: "majority" },
};
// Step 3: Use withTransaction to start a transaction, execute the callback, and commit (or abort on error)
// Note: The callback for withTransaction MUST be async and/or return a Promise.
try {
await session.withTransaction(async () => {
// Step 4: Execute the queries you would like to include in one atomic transaction
// Important:: You must pass the session to the operations
await accounts.updateOne(
{ name: userSubtractPoints },
{ $inc: { browniePoints: -1 * pointVolume } },
{ session }
);
await accounts.updateOne(
{ name: userAddPoints },
{ $inc: { browniePoints: pointVolume } },
{ session }
);
await browniePointsTrades.insertOne(
{
userAddPoints: userAddPoints,
userSubtractPoints: userSubtractPoints,
pointVolume: pointVolume,
},
{ session }
);
}, transactionOptions);
} catch (err) {
// Step 5: Handle errors with a transaction abort
await session.abortTransaction();
} finally {
// Step 6: End the session when you complete the transaction
await session.endSession();
}
}

Volver

Lea