Skip to main content

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.

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