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.
Modelo de datos
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.
{ "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" } } } } } }
Configuración de fragmentos
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 ... }
Insert
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.
Insertar un solo documentoinsertOne() ()
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}`))
Insertar uno o más documentosinsertMany() ()
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}`))
Update
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: "" } } )
Actualizar un solo documentoupdateOne() ()
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.
Actualizar uno o más documentos (updateMany())
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}`))
Insertar documentos
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}`))
Operadores de actualización de campo
Los operadores de campo le permiten modificar los campos y valores de un documento.
Establecer el valor de un campo
Puede utilizar el operador $set para establecer el valor de un solo campo sin afectar otros campos de un documento.
{ "$set": { "<Field Name>": <Value>, ... } }
Renombrar un campo
Puede utilizar el operador $rename para cambiar el nombre de un solo campo en un documento.
{ "$rename": { "<Current Field Name>": <New Field Name>, ... } }
Incrementar un valor
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>, ... } }
Multiplicar un valor
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>, ... } }
Operadores de actualización de arreglos
Los operadores de matriz le permiten trabajar con valores dentro de matrices.
Insertar un elemento en una matriz
Puede utilizar el operador $push para agregar un valor al final de un campo de matriz.
{ "$push": { "<Array Field Name>": <New Array Element>, ... } }
Extraer el último elemento de una matriz
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>, ... } }
Agregar un elemento único a una matriz
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>, ... } }
Eliminar elementos de una matriz
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>, ... } }
Actualizar todos los elementos de una matriz
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 ] }
Actualizar elementos específicos en una matriz
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 ] }
Borrar
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.
Eliminar un solo documentodeleteOne() ()
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.
Eliminar uno o más documentosdeleteMany() ()
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}`))
Escrituras masivas
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}); };
Transacciones
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:
Obtenga y comience una sesión de cliente con
client.startSession().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" }, }) 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
sessiona cada consulta para garantizar que se incluya en la transacción.await accounts.updateOne( { name: userSubtractPoints }, { $inc: { browniePoints: -1 * pointVolume } }, { session } ); 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(); } 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(); } }