MongoDB | CSharp
- MongoDB | CSharp
Documentação Fácil
Configuração Inicial e Conexão
using MongoDB.Driver;
var client = new MongoClient("mongodb://localhost:27017");
var database = client.GetDatabase("nomeDoBanco");
var collection = database.GetCollection<BsonDocument>("nomeDaColecao");
Configuração Avançada e Conexão
var settings = MongoClientSettings.FromUrl(new MongoUrl("mongodb://username:password@localhost:27017"));
var client = new MongoClient(settings);
var database = client.GetDatabase("nomeDoBanco");
Modelos de Dados
public class MeuModelo
{
public ObjectId Id { get; set; }
public string Propriedade1 { get; set; }
// Outras propriedades
}
var collection = database.GetCollection<MeuModelo>("nomeDaColecao");
Inserção de Documentos
var documento = new BsonDocument { { "chave", "valor" } };
collection.InsertOne(documento);
Inserção em Massa
var documentos = new List<MeuModelo>
{
new MeuModelo { Propriedade1 = "valor1" },
// outros documentos
};
collection.InsertMany(documentos);
Consulta e Filtros
var filtro = Builders<BsonDocument>.Filter.Eq("chave", "valor");
var resultado = collection.Find(filtro).FirstOrDefault();
Consultas Complexas
warning
FilterDefinition são imutáveis, depois de criado eu não consigo alterar. Se precisar mesclar dois filtros use da seguinte forma filtro1 & filtro2
LINQ
var resultados = collection.AsQueryable()
.Where(x => x.Propriedade1 == "valor")
.OrderBy(x => x.Propriedade2)
.ToList();
FilterDefinition
var filtroBuilder = Builders<Revenda>.Filter;
var filtro = FilterDefinition<Revenda>.Empty;
filtro = filtroBuilder.AnyEq(x => x.EmailsResponsaveis, emailResponsavel) & filtroBuilder.Ne(x => x.Deletado, true);
Multiplos filtros
using MongoDB.Driver;
var builder = Builders<Usuario>.Filter;
var filtro = builder.Eq(x => x.Ativo, true)
& builder.Gte(x => x.Idade, 18)
& builder.Regex(x => x.Nome, new MongoDB.Bson.BsonRegularExpression("joao", "i"));
var usuarios = await collection.Find(filtro).ToListAsync();
Validar Filtro criado
- Para validar qual foi o filtro gerado, utilize o seguinte comando:
// FilterDefinition<Cliente>
novoFiltro.Render(
BsonSerializer.SerializerRegistry.GetSerializer<Cliente>(),
BsonSerializer.SerializerRegistry
);
Atualização de Documentos
Operadores
- AddToSetEach - método indica que queremos adicionar múltiplos valores ("x" e "y") ao array "z" garantindo que não haverá duplicatas.
var filtro = Builders<PerfilAcesso>.Filter.Eq("Nome", NomePerfilAdministrador);
var novosModulos = new[] { "vendasPorEmpresa", "comprasPorEmpresa" };
var atualizacao = Builders<PerfilAcesso>.Update.AddToSetEach("Modulos", novosModulos);
await DbSet.UpdateManyAsync(filtro, atualizacao);
var filtro = Builders<BsonDocument>.Filter.Eq("chave", "valor");
var atualizacao = Builders<BsonDocument>.Update.Set("chave", "novoValor");
collection.UpdateOne(filtro, atualizacao);
Atualizações Condicionais de uma propriedade e em Massa
var filtro = Builders<MeuModelo>.Filter.Gt(x => x.PropriedadeNum, 100);
var atualizacao = Builders<MeuModelo>.Update.Set(x => x.Propriedade1, "novoValor");
collection.UpdateMany(filtro, atualizacao);
Atualizações Condicionais de uma propriedade dentro de um array e em Massa
var filtro = Builders<Contrato>.Filter.Empty;
var atualizacao = Builders<Contrato>.Update.Set("Empresas.$[].DataAtivacao", new DateTime(2023, 1, 1));
await DbSet.UpdateManyAsync(filtro, atualizacao);
/*
{
"Deletado" : false,
"Ativo" : true,
"DataCadastro" : ISODate("2024-03-07T11:13:04.956+0000"),
"DataAtualizacao" : null,
"Descricao" : "Descrição Padrão",
"Empresas" : [
{
"Ativa" : true,
"Dispositivos" : [
],
"DataAtivacao" : ISODate("2022-01-01T00:00:00.000+0000")
},
{
"Ativa" : true,
"Dispositivos" : [
],
"DataAtivacao" : ISODate("2022-01-01T00:00:00.000+0000")
}
],
"Usuarios" : [
]
}
*/
Remoção de Documentos
var filtro = Builders<BsonDocument>.Filter.Eq("chave", "valor");
collection.DeleteOne(filtro);
Trabalhando com Arrays
var filtro = Builders<BsonDocument>.Filter.Eq("chave", "valor");
var update = Builders<BsonDocument>.Update.Pull("arrayKey", "valorParaRemover");
collection.UpdateOne(filtro, update);
Remoção e atualização de um item de array
- Exemplo de json
{
"id": "1",
"nome": "Exemplo",
"itens": [
{ "itemId": "A1", "valor": 10 },
{ "itemId": "A2", "valor": 20 }
]
}
Atualização de uma propriedade de um item do Array
var filtro = Builders<BsonDocument>.Filter.Eq("itens.itemId", "A1");
var atualizacao = Builders<BsonDocument>.Update.Set("itens.$.valor", 15);
collection.UpdateOne(filtro, atualizacao);
Explicação do $
- No MongoDB, o $ é um operador posicional usado nas atualizações. Ele tem um papel especial: identifica o índice do primeiro elemento no array que corresponde ao critério do filtro especificado na operação de atualização. Isso permite que você atualize um item específico dentro de um array sem precisar saber sua posição exata
var filtro = Builders<BsonDocument>.Filter.Eq("itens.itemId", "A1");
var atualizacao = Builders<BsonDocument>.Update.Set("itens.$.valor", 15);
collection.UpdateOne(filtro, atualizacao);
- O filtro Builders < BsonDocument >.Filter.Eq("itens.itemId", "A1")` está buscando um documento onde, dentro do array itens, existe um elemento com itemId igual a "A1".
- Na parte de atualização,
<b>Builders < BsonDocument >.Update.Set("itens.$.valor", 15)</b>, o $ é usado para referenciar o índice do elemento encontrado pelo filtro. Ou seja, ele diz ao MongoDB: "No documento que você encontrou, atualize o campo valor do elemento específico em itens que correspondeu ao nosso filtro para 15".
- Assim, o operador
<b>$</b> permite que você faça atualizações direcionadas em elementos de array, baseando-se na condição que eles atendem, sem a necessidade de saber a posição exata do elemento no array.
- No MongoDB, o $ é um operador posicional usado nas atualizações. Ele tem um papel especial: identifica o índice do primeiro elemento no array que corresponde ao critério do filtro especificado na operação de atualização. Isso permite que você atualize um item específico dentro de um array sem precisar saber sua posição exata
var filtro = Builders<BsonDocument>.Filter.Eq("itens.itemId", "A1");
var atualizacao = Builders<BsonDocument>.Update.Set("itens.$.valor", 15);
collection.UpdateOne(filtro, atualizacao);
- O filtro Builders < BsonDocument >.Filter.Eq("itens.itemId", "A1")` está buscando um documento onde, dentro do array itens, existe um elemento com itemId igual a "A1".
- Na parte de atualização,
<b>Builders < BsonDocument >.Update.Set("itens.$.valor", 15)</b>, o $ é usado para referenciar o índice do elemento encontrado pelo filtro. Ou seja, ele diz ao MongoDB: "No documento que você encontrou, atualize o campo valor do elemento específico em itens que correspondeu ao nosso filtro para 15". - Assim, o operador
<b>$</b>permite que você faça atualizações direcionadas em elementos de array, baseando-se na condição que eles atendem, sem a necessidade de saber a posição exata do elemento no array.
Remoção de um Item do Array
- Pull - retirar
var filtro = Builders<BsonDocument>.Filter.Eq("id", "1");
var atualizacao = Builders<BsonDocument>.Update.PullFilter("itens", Builders<BsonDocument>.Filter.Eq("itemId", "A2"));
collection.UpdateOne(filtro, atualizacao);
- Se for usar uma lista como propriedade e for usar expression ficará dessa forma:
Builders<Cliente>.Update.PullFilter(c => c.DataAgendamentosExecutados, date => date <= dateToRemove);
Criação de Índices
collection.Indexes.CreateOne(new CreateIndexModel<BsonDocument>(new IndexKeysDefinitionBuilder<BsonDocument>().Ascending("chaveIndexada")));
Transações
using (var session = client.StartSession())
{
session.StartTransaction();
try
{
collection.InsertOne(session, new MeuModelo { /* ... */ });
// Outras operações
session.CommitTransaction();
}
catch
{
session.AbortTransaction();
}
}
Segurança
-
Create a new user.
use admin
db.createUser({
user: "username",
pwd: "password",
roles: [
{ role: "readWrite", db: "yourDatabase" },
// Additional roles if needed
]
}) -
Grant role to an existing user.
use admin
db.grantRolesToUser("username", [{ role: "read", db: "anotherDatabase" }]) -
Create custom role.
use admin
db.createRole({
role: "customRole",
privileges: [
{ resource: { db: "yourDatabase", collection: "" }, actions: ["find", "update"] },
// Additional privileges if needed
],
roles: []
}) -
Grant custom role to an existing user.
use admin
db.grantRolesToUser("username", [{ role: "customRole", db: "yourDatabase" }]) -
Revoke role from user.
use admin
db.revokeRolesFromUser("username", ["readWrite"]) -
View roles for user
use admin
db.getUser("username").roles