Menu Docs
Página inicial do Docs
/
MongoDB Atlas
/ / /

Gravar dados no Atlas MongoDB - Funções

Nesta página

  • Modelo de dados
  • Configuração do trecho
  • Insert
  • Inserir um único documento (insertOne())
  • Inserir um ou mais documentos (insertMany())
  • Update
  • Atualizar um único documento (updateOne())
  • Atualizar um ou mais documentos (updateMany())
  • Documentos do Upsert
  • Operadores de atualização de campo
  • Operadores de atualização de array
  • Excluir
  • Excluir um único documento (deleteOne())
  • Excluir um ou mais documentos (deleteMany())
  • Gravações em massa
  • Transações

Os exemplos nesta página demonstram como utilizar a API de query do MongoDB em uma função para inserir, atualizar e excluir dados em seu Atlas cluster.

Observação

As fontes de dados federadas não suportam operações de gravação.

Os exemplos nesta página usam uma coleção chamada store.items que modela vários itens disponíveis para compra em uma loja virtual. Cada item possui um name, um inventário quantity e uma array de clientes reviews.

O JSON schema 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 um trecho de código em uma função, você deve primeiro instanciar um identificador de coleção do 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 ...
}

Insira operações em um ou mais documentos e adicione-os a uma coleção MongoDB.

Retornam documentos que descrevem os resultados da operação.

Você pode inserir um único documento usando o método collection.insertOne().

O seguinte trecho de função insere um único documento de item na coleção 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}`))

Você pode inserir vários documentos ao mesmo tempo usando o método collection.insertMany().

O trecho de função abaixo insere vários documentos de itens na collection 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}`))

As operações de atualização localizam documentos existentes em uma collection do MongoDB e modificam seus dados. Você usa a sintaxe de query padrão do MongoDB para especificar quais documentos atualizar e operadores de atualização para descrever as alterações a serem aplicadas aos documentos correspondentes.

Ao executar operações de atualização, as Funções do Atlas adicionam temporariamente um campo reservado, _id__baas_transaction, aos documentos. Depois que um documento é atualizado com êxito, as funções do Atlas removem esse campo.

Se você quiser usar outra ferramenta para modificar dados em uma coleção, certifique-se de $unset este campo antes de fazer alterações.

Por exemplo, se você estiver usando o shell mongosh para atualizar documentos na coleção de produtos, seu comando poderá se assemelhar ao código a seguir:

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

Você pode atualizar um único documento usando o método collection.updateOne().

O seguinte snippet de função atualiza o name de um único documento na coleção items de lego para blocks e adiciona um price de 20.99:

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, você pode atualizar um único documento usando collection.findOneAndUpdate() ou collection.findOneAndReplace(). Ambos os métodos permitem encontrar, modificar e retornar o documento atualizado em uma única operação.

Você pode atualizar vários documentos em uma coleção usando o método collection.updateMany().

O seguinte trecho de função atualiza todos os documentos na coleção items multiplicando seus valores de 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}`))

Se uma operação de atualização não corresponder a nenhum documento na coleção, você poderá inserir automaticamente um único novo documento na coleção que corresponda à query de atualização definindo a opção upsert como true.

O trecho de função a seguir atualiza um documento na coleção items que tem name de board game incrementando seu quantity por 5. A opção upsert está habilitada, portanto, se nenhum documento tiver um valor name de "board game", o MongoDB inserirá um novo documento com o campo name definido como "board game" e o valor quantity definido como 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}`))

Os operadores de campo permitem modificar os campos e valores de um documento.

Você pode utilizar o operador $set para definir o valor de um único campo sem afetar outros campos em um documento.

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

Você pode usar o operador $rename para alterar o nome de um campo único em um documento.

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

Você pode utilizar o operador $inc para adicionar um número especificado ao valor atual de um campo. O número pode ser positivo ou negativo.

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

Você pode usar o operador $mul para multiplicar um número especificado com o valor atual de um campo. O número pode ser positivo ou negativo.

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

Operadores de arrays permitem trabalhar com valores dentro de arrays.

Você pode usar o operador $push para adicionar um valor ao final de um campo de array.

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

Você pode usar o operador $pop para remover o primeiro ou último elemento de um campo de array. Especifique -1 para remover o primeiro elemento e 1 para remover o último elemento.

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

Você pode usar o operador $addToSet para adicionar um valor a um campo de array se esse valor ainda não estiver incluído na array. Se o valor já estiver presente, $addToSet não faz nada.

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

Você pode usar o operador $pull para remover todas as instâncias de quaisquer valores que correspondam a uma condição especificada de um campo de vetor.

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

Você pode utilizar o operador $[] (Todas as Atualizações Posicionais) para atualizar todos os elementos em um campo de array:

Exemplo

Considere uma collection students que descreve alunos individuais em uma turma. Cada um dos documentos inclui um campo grades que contém uma array de números:

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

A seguinte operação de atualização adiciona 10 a todos os valores na array grades de cada aluno:

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

Após a atualização, o valor de cada nota aumenta em intervalos de 10:

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

Você pode usar o operador $[element] (Atualização posicional filtrada) para atualizar elementos específicos em um campo de array baseado em um filtro de array:

Exemplo

Considere uma coleção students que descreve alunos individuais em uma turma. Cada documento inclui um campo grades que contém uma array de números, alguns dos quais são maiores que 100:

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

A seguinte operação de atualização define todos os valores de nota maiores que 100 para exatamente 100:

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

Após a atualização, todos os valores de nota maiores que 100 serão definidos como exatamente 100, e todas as outras notas não serão afetadas:

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

As operações de exclusão localizam documentos existentes em uma coleção do MongoDB e os removem. Você usa a sintaxe de query MongoDB padrão para especificar quais documentos excluir.

Você pode excluir um único documento de uma coleção usando o método collection.deleteOne().

O seguinte snippet de função exclui um documento da coleção items que tem um valor name de 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}`))

Alternativamente, você pode atualizar um único documento usando collection.findOneAndDelete(). Este método permite localizar, remover e devolver o documento excluído em uma única operação.

Você pode excluir vários itens de uma coleção utilizando o método collection.deleteMany().

O seguinte trecho exclui todos os documentos na coleção items que não têm nenhum 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}`))

Uma escrita em massa combina múltiplas operações de escrita em uma única operação. Você pode emitir um comando de escrita em massa utilizando o 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});
};

O MongoDB oferece suporte a transações de vários documentos que permitem ler e gravar vários documentos atomicamente, mesmo em coleções.

Para realizar uma transação:

  1. Obter e iniciar uma sessão de cliente com client.startSession().

  2. Chame session.withTransaction() para definir a transação. O método usa uma função de chamada de resposta assíncrona e, opcionalmente, um objeto de configuração que define configurações personalizadas de leitura e gravação para a transação.

    session.withTransaction(async () => {
    // ... Run MongoDB operations in this callback
    }, {
    readPreference: "primary",
    readConcern: { level: "local" },
    writeConcern: { w: "majority" },
    })
  3. Na função de chamada de resposta da transação, execute as queries do MongoDB que você deseja incluir na transação. Certifique-se de passar session para cada query para que ela seja incluída na transação.

    await accounts.updateOne(
    { name: userSubtractPoints },
    { $inc: { browniePoints: -1 * pointVolume } },
    { session }
    );
  4. Se a chamada de resposta encontrar um erro, chame session.abortTransaction() para interromper a transação. Uma transação abortada não modifica nenhum dado.

    try {
    // ...
    } catch (err) {
    await session.abortTransaction();
    }
  5. Quando a transação estiver concluída, ligue para session.endSession() para encerrar a sessão e recursos gratuitos.

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

O exemplo a seguir cria dois usuários, "henry" e "michelle", e a usa uma transação para mover "browniePoints" entre esses usuários Atomicamente:

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

Voltar

Leia