Overview
Los ejemplos en esta página demuestran cómo usar la query API de MongoDB en una función para insertar, actualizar y borrar datos en tu clúster de Atlas.
Nota
Federated data sources do not support write operations.
modelo de datos
Los ejemplos en esta página utilizan una colección llamada store.items que modela varios artículos disponibles para la compra en un almacenar en línea. Cada elemento tiene un name, un inventario quantity y un arreglo de reviews de clientes.
{ "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 usar un code snippet en una función, primero debes crear una instancia de un handle 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 documento (insertOne())
Puedes insertar un solo documento utilizando el método collection.insertOne().
El siguiente función snippet inserta un documento individual 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}`))
Inserte Uno o Más Documentos (insertMany())
Puedes insertar varios documentos al mismo tiempo utilizando el collection.insertMany() método.
El siguiente función snippet inserta múltiples documentos de ítems en la colección items:
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.
Nota
While running update operations, Atlas App Services temporarily adds a reserved field, _id__baas_transaction, to documents. If you modify data used by your app outside of App Services, you may need to unset this field. For more information, see Transactional Locks.
Actualiza un documento único (updateOne())
Puede actualizar un solo documento utilizando el método collection.updateOne().
El siguiente fragmento de función actualiza el name de un solo documento en la items colección lego blocks price de a y agrega un 20.99 de:
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}`))
Alternativamente, puedes actualizar un solo documento usando collection.findOneAndUpdate() o collection.findOneAndReplace(). Ambos métodos le permiten encontrar, modificar y devolver el documento actualizado en una sola 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 en la colección items multiplicando sus valores quantity por 10:
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}`))
Realizar inserción de documentos
Si una operación de actualización no coincide con ningún documento en la colección, puedes insertar automáticamente un nuevo documento en la colección que coincida con la query de actualización configurando la opción upsert en true.
El siguiente fragmento de función actualiza un documento en la colección items que tenga un name de board game incrementando su quantity en 5. La opción upsert está habilitada, por lo que si ningún documento tiene un valor name de "board game" entonces MongoDB inserta un nuevo documento con el campo name configurado a "board
game" y el valor de quantity establecido en 5:
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
Se puede usar el operador $set para asignar el valor de un único campo sin afectar a otros campos en un documento.
{ "$set": { "<Field Name>": <Value>, ... } }
Renombrar un campo
Puedes usar el operador $rename para cambiar el nombre de un solo campo en un documento.
{ "$rename": { "<Current Field Name>": <New Field Name>, ... } }
Incrementar un valor
Puedes usar el operador $inc para añadir una cantidad específica 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 especificado con 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 arreglo le permiten trabajar con valores dentro de los arreglos.
Insertar un elemento en un arreglo.
Puedes usar el operador $push para agregar un valor al final de un campo de arreglo.
{ "$push": { "<Array Field Name>": <New Array Element>, ... } }
Extraer el último elemento de un arreglo
Puedes utilizar el operador $pop para remover el primer o el último elemento de un campo de arreglo. Especifique -1 para remover el primer elemento y 1 para remover el último elemento.
{ "$pop": { "<Array Field Name>": <-1 | 1>, ... } }
Añadir un elemento único a un arreglo
Puedes utilizar el operador $addToSet para añadir un valor a un campo de arreglo si ese valor aún no está incluido en el arreglo. Si el valor ya está presente, $addToSet no hace nada.
{ "$addToSet": { "<Array Field Name>": <Potentially Unique Value>, ... } }
Eliminar elementos de una matriz
Puede usar el operador $pull para remover todas las instancias de cualquier valor que coincida con una condición especificada de un campo de arreglo.
{ "$pull": { "<Array Field Name>": <Value | Expression>, ... } }
Actualizar todos los elementos de una matriz
Puedes usar el $[] (Actualización Posicional Total) operador para actualizar todos los elementos en un campo de arreglo:
Ejemplo
Considera una colección de students que describa a los estudiantes individuales de una clase. Los documentos incluyen cada uno un campo grades que contiene un arreglo 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 suma 10 a todos los valores en el arreglo grades de cada estudiante:
await students.updateMany( {}, { $inc: { "grades.$[]": 10 } }, )
Después de la actualización, cada valor de calificación ha aumentado 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 un arreglo
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 los estudiantes 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 calificaciones mayores a 100 se establecen exactamente en 100 y el resto se mantienen igual:
{ "_id" : 1, "grades" : [ 15, 92, 90 ] } { "_id" : 2, "grades" : [ 18, 100, 100 ] } { "_id" : 3, "grades" : [ 15, 100, 100 ] }
Borrar
Las operaciones de borrado buscan documentos existentes en una colección de MongoDB y los remueven. Utilizas la sintaxis estándar de query de MongoDB para especificar los documentos que deseas borrar.
Borrar un solo documento (deleteOne())
Puedes borrar un solo documento de una colección utilizando el método collection.deleteOne().
The following function snippet deletes one document in the items collection that has a name value of lego:
const query = { "name": "lego" }; itemsCollection.deleteOne(query) .then(result => console.log(`Deleted ${result.deletedCount} item.`)) .catch(err => console.error(`Delete failed with error: ${err}`))
O, de forma alternativa, puedes actualizar un único documento utilizando collection.findOneAndDelete(). Este método te permite localizar, remover y recuperar el documento borrado en una sola operación.
Borrar uno o más documentos (deleteMany())
Puede eliminar varios elementos de una colección utilizando el collection.deleteMany() método.
El siguiente snippet borra 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}`))
Guardados masivos
Una operación masiva combina varias operaciones de guardado en una sola operación. Puedes emitir un comando de guardado masivo usando el método collection.bulkWrite().
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 multidocumento que permiten leer y guardar varios documentos atómicamente, incluso entre 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.session.withTransaction(async () => { // ... Run MongoDB operations in this callback }) En la función de retorno de la transacción, ejecuta las queries de MongoDB que deseas incluir en la transacción. Asegúrese de pasar el
sessiona cada query para asegurarse de que esté incluido en la transacción.await accounts.updateOne( { name: userSubtractPoints }, { $inc: { browniePoints: -1 * pointVolume } }, { session } ); Si la función de retorno encuentra un error, llama a
session.abortTransaction()para detener la transacción. Una transacción abortada 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 mover "browniePoints" entre esos usuarios de forma atómica:
exports = function () { const client = context.services.get("mongodb-atlas"); const db = client.db("exampleDatabase"); const accounts = db.collection("accounts"); const 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: 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 3: 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 } ); }); } catch (err) { // Step 4: Handle errors with a transaction abort await session.abortTransaction(); } finally { // Step 5: End the session when you complete the transaction await session.endSession(); } }