Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /
Consulta de MongoDB Atlas

Guardar datos en MongoDB Atlas - Funciones

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.

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.

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 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 ...
}

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.

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}`))

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}`))

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.

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.

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}`))

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}`))

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

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>, ... } }

Puedes usar el operador $rename para cambiar el nombre de un solo campo en un documento.

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

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>, ... } }

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>, ... } }

Los operadores de arreglo le permiten trabajar con valores dentro de los arreglos.

Puedes usar el operador $push para agregar un valor al final de un campo de arreglo.

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

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>, ... } }

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>, ... } }

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>, ... } }

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 ] }

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 ] }

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.

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.

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}`))

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});
};

MongoDB admite transacciones multidocumento que permiten leer y guardar varios documentos atómicamente, incluso entre 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.

    session.withTransaction(async () => {
    // ... Run MongoDB operations in this callback
    })
  3. 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 session a cada query para asegurarse de que esté incluido en la transacción.

    await accounts.updateOne(
    { name: userSubtractPoints },
    { $inc: { browniePoints: -1 * pointVolume } },
    { session }
    );
  4. 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();
    }
  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 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();
}
}

Volver

Lea