mongo-00

É inegável a importância dos bancos de dados relacionais dentro do mundo corporativo. O surgimento desta tecnologia revolucionou o tratamento de informações nos mais variados ramos de atuação, conferindo agilidade e flexibilidade às organizações em suas operações cotidianas. Este uso em larga escala de bases relacionais deve certamente continuar, tendo como pilares a linguagem SQL e a praticidade desta última na manipulação de dados.

Por mais que a tecnologia relacional atenda a um amplo escopo de necessidades, em alguns cenários bem específicos esta abordagem pode não ser a solução mais adequada:

  • Questões como uma alta disponibilidade e a capacidade de um sistema de banco de dados se adaptar a níveis de uso crescentes (escalabilidade) costumam exigir pesados investimentos em infraestrutura. Nem sempre existirão recursos disponíveis (financeiros ou não) para atender a tais demandas imediatamente;
  • A estrutura rígida de linhas e colunas das tabelas relacionais também será um fator limitante em determinados contextos. A adaptação de uma base convencional para agrupamentos de dados mais complexos pode se revelar uma tarefa bastante árdua, sobretudo se o conteúdo em questão apresentar um formato variável.

Uma opção às dificuldades aqui levantadas seria o uso de uma solução NoSQL (sigla interpretada por alguns como “Not only SQL”). Tecnologias em conformidade com este paradigma costumam adotar uma estrutura diferente daquela tipicamente relacional, de forma a oferecer assim uma resposta a requisitos como alta disponibilidade, escalabilidade e a necessidade de uma estrutura para armazenamento mais flexível. Diversos são os bancos de dados NoSQL disponíveis no mercado, com o MongoDB correspondendo a uma das alternativas mais populares entre desenvolvedores de software.

O objetivo deste artigo é trazer uma visão geral do MongoDB, bem como de que maneira o mesmo pode ser utilizado na implementação de projetos baseados no .NET Framework.

Um pouco mais sobre o MongoDB

O nome MongoDB tem sua origem na palavra inglesa “humongous”, termo este geralmente empregado para expressar algo considerado gigantesco. Trata-se de uma solução gratuita e open source mantida por uma empresa chamada MongoDB Inc. (anteriormente conhecida como 10gen), encontrando-se atualmente (Fevereiro/2016) na versão 3.2.

Do ponto de vista estrutural o MongoDB conta com as seguintes características:

  • Ao invés de registros organizados em tabelas relacionais formadas por colunas com um tipo pré-definido, um banco do MongoDB é composto por coleções; cada coleção, por sua vez, é constituída por uma série de documentos (Imagem 1). Por esse motivo este produto é classificado como um banco de dados NoSQL baseado em documento;
  • Os documentos no MongoDB são formados por campos (o equivalente a colunas no modelo relacional), empregando um formato conhecido como BSON para o armazenamento de informações. Já o padrão BSON (abreviação de binary JSON) representa uma variação da especificação JSON com suporte à manipulação de dados binários, além de tipos convencionais como strings ou valores numéricos;
  • A utilização de uma estrutura baseada em JSON torna o MongoDB um banco schemaless, ou seja, sem um esquema rígido. Isto permite a utilização de um formato flexível para os diferentes documentos que venham a compor uma coleção, diferentemente das colunas que seguem um padrão pré-definido para todos os registros em uma tabela relacional;
  • Todo documento criado no MongoDB conta com um campo chamado “_id”, o qual nada mais é do que um identificador único e gerado automaticamente no momento da inclusão deste elemento;
  • Além dos aspectos mencionados, o MongoDB possui ainda o suporte a informações geoespaciais (incluindo latitude e longitude) e permite a criação de índices para a otimização de consultas.

mongo-01

Imagem 1. Estrutura geral de um banco de dados no MongoDB

OBSERVAÇÃO: maiores detalhes sobre a arquitetura empregada pelo MongoDB podem ser encontrados na seção “Referências”.

Instalando o MongoDB no Windows

O download da versão do MongoDB para Windows pode ser efetuado através do seguinte link:

https://www.mongodb.org/downloads

ATENÇÃO: Os procedimentos descritos nesta seção foram realizados em uma máquina com o Windows 10 Professional instalado (estas ações são válidas, a princípio, em outras versões do Windows suportadas pelo MongoDB).

Por motivos de simplificação, a instalação do MongoDB foi efetuada no diretório C:\MongoDB\. Também será necessário criar o diretório C:\data\db\, o qual corresponde ao espaço utilizado pelo MongoDB para a geração de arquivos com dados e logs.

Para ativar o uso do MongoDB acionar o executável mongod.exe, instalado em C:\MongoDB\bin\. Com isto o servidor deste banco NoSQL estará no ar (Imagem 2). Vale destacar que a execução do arquivo mongod.exe pode acontecer tanto via prompt de comando, quanto por meio do agendamento de uma tarefa no Windows.

mongo-02
Imagem 2. O utilitário mongod.exe em execução

A execução de ações em bancos de dados do MongoDB pode ser feita por meio do utilitário de linha de comando mongo.exe (também criado em C:\MongoDB\bin\). Na Imagem 3 é possível observar esta aplicação em ação.

mongo-03
Imagem 3. O utilitário mongo.exe em execução

MongoDB e o .NET Framework

O package para acesso ao MongoDB em soluções .NET (MongoDB.Driver) pode ser instalado via NuGet no Visual Studio, como indicado na Imagem 4. Para os exemplos descritos nesta seção foi utilizada a versão 2.2.3 deste driver.

mongo-04
Imagem 4. Adicionando o MongoDB.Driver a uma aplicação .NET

Ao se realizar este procedimento serão adicionadas ao projeto as referências destacadas na Imagem 5:

mongo-05
Imagem 5. Bibliotecas do MongoDB adicionadas a uma aplicação .NET

Para os exemplos envolvendo a integração MongoDB-C# será utilizada a classe Cidade, cuja definição encontra-se na Listagem 1:

  • A propriedade _id corresponde ao identificador único de um documento, tendo sido declarada como do tipo ObjectId (namespace MongoDB.Bson);
  • Também foram definidos campos representando o nome e o estado de uma cidade.
using MongoDB.Bson;

namespace TesteMongoDB
{
    class Cidade
    {
        public ObjectId _id { get; set; }
        public string Nome { get; set; }
        public string Pais { get; set; }
    }
}

Listagem 1: Classe Cidade

A Listagem 2 demonstra a inclusão de uma cidade em um banco de dados chamado ExemploCSharp:

  • Uma primeira variável foi declarada de forma a armazenar a conexão de acesso local ao servidor do MongoDB (por default, o mesmo é instalado na porta 27017);
  • Será gerada então uma instância da classe MongoClient (namespace MongoDB.Driver), que servirá de base para o acesso aos bancos NoSQL existentes em um servidor;
  • Uma referência a um banco de dados será obtida invocando o método GetDabase do objeto MongoClient; esta operação recebe como parâmetro o nome de uma base, trazendo como resultado uma instância do tipo IMongoDatabase (namespace namespace MongoDB.Driver);
  • Com a referência de IMongoDatabase será acionado o método GetCollection, com este último recebendo como parâmetros a classe que representa um documento e o nome da coleção a ser manipulada. O retorno desta ação será uma referência baseada na interface genérica IMongoCollection (namespace MongoDB.Driver);

Uma instância do tipo Cidade é então criada, com o preenchimento das propriedades que serão persistidas no banco de dados. Por fim, o método InsertOne será executado, procedendo com a inclusão dos dados na base; neste momento constará na propriedade _id o valor único gerado pelo MongoDB para esse novo documento.

...

string connectionString = "mongodb://localhost:27017";

MongoClient client = new MongoClient(connectionString);
IMongoDatabase db = client.GetDatabase("ExemploCSharp");

var cidades = db.GetCollection<Cidade>("cidades");

Cidade cidade = new Cidade();
cidade.Nome = "Roma";
cidade.Pais = "Italia";

cidades.InsertOne(cidade);

ObjectId _idInclusao = cidade._id;

...

Listagem 2: Adicionando um novo documento

É importante ressaltar que, na eventualidade de um banco e/ou coleção ainda não existir fisicamente, o procedimento descrito nesta segunda listagem fará com que tais elementos sejam automaticamente criados. Na Imagem 6 está o resultado de uma consulta à coleção “cidades” após a execução deste último trecho de código:

mongo-06
Imagem 6. Coleção após da inclusão de uma primeira cidade

O próximo passo agora será alterar a classe cidade, adicionando à mesma um campo que referencie o estado/província (Listagem 3):

using MongoDB.Bson;

namespace TesteMongoDB
{
    class Cidade
    {
        public ObjectId _id { get; set; }
        public string Nome { get; set; }
        public string Estado { get; set; }
        public string Pais { get; set; }
    }
}

Listagem 3: Classe Cidade após inclusão do campo Estado

A Listagem 4 apresenta um trecho de código que efetuará um teste já contemplando o uso da propriedade Estado:

...

string connectionString = "mongodb://localhost:27017";

MongoClient client = new MongoClient(connectionString);
IMongoDatabase db = client.GetDatabase("ExemploCSharp");

var cidades = db.GetCollection<Cidade>("cidades");

Cidade cidade = new Cidade();
cidade.Nome = "Sao Paulo";
cidade.Estado = "Sao Paulo";
cidade.Pais = "Brasil";

cidades.InsertOne(cidade);

ObjectId _idInclusao = cidade._id;

...

Listagem 4: Adicionando um segundo documento

Para localização de documentos o driver do MongoDB disponibiliza o método Find, que deverá ser invocado a partir de uma coleção (Listagem 5). A expressão lambda informada como parâmetro neste exemplo retornará sempre true, de forma a retornar todos os elementos existentes:

...

string connectionString = "mongodb://localhost:27017";

MongoClient client = new MongoClient(connectionString);
IMongoDatabase db = client.GetDatabase("ExemploCSharp");

List<Cidade> cidades = db.GetCollection<Cidade>("cidades")
    .Find(_ => true).ToList();

...

Listagem 5: Retornando todos os elementos de uma coleção

Expressões lambda mais específicas podem ser utilizadas, de forma a permitir a localização de itens específicos (Listagem 6):

...

string connectionString = "mongodb://localhost:27017";

MongoClient client = new MongoClient(connectionString);
IMongoDatabase db = client.GetDatabase("ExemploCSharp");

Cidade cidade = db.GetCollection<Cidade>("cidades")
    .Find(c => c.Nome == "Roma").ToList().First();

...

Listagem 6: Localizando um documento específico

Na Listagem 7 é possível observar um exemplo envolvendo a atualização de um documento:

  • Inicialmente será localizado o elemento a ser modificado, empregando-se para isto o método Find em conjunto com uma expressão lambda;
  • Modificações são então realizadas na referência obtida;
  • Na sequência o método ReplaceOne é invocado. O primeiro parâmetro informado representa uma expressão lambda baseada na propriedade _id, ao passo que o segundo valor é a própria instância do tipo Cidade com os dados a serem atualizados.
...

string connectionString = "mongodb://localhost:27017";

MongoClient client = new MongoClient(connectionString);
IMongoDatabase db = client.GetDatabase("ExemploCSharp");

var cidades = db.GetCollection<Cidade>("cidades");

Cidade cidade = cidades
    .Find(c => c.Nome == "Sao Paulo").ToList().First();
cidade.Estado = "SP";

cidades.ReplaceOne(c => c._id == cidade._id, cidade);

...

Listagem 7: Atualizando um documento

As modificações efetuadas até este ponto podem ser visualizadas na Imagem 7.

mongo-07
Imagem 7. Coleção após inclusões e alterações

Finalmente a Listagem 8 traz um caso de exclusão de um documento:

  • Trata-se de um processo bastante similar àquele descrito para alterações, envolvendo novamente o uso do método Find;
  • O método DeleteOne é acionado, recebendo como parâmetro uma expressão lambda cujo filtro fará uso da propriedade _id e procedendo com a remoção do elemento em questão.
...

string connectionString = "mongodb://localhost:27017";

MongoClient client = new MongoClient(connectionString);
IMongoDatabase db = client.GetDatabase("ExemploCSharp");

var cidades = db.GetCollection<Cidade>("cidades");

cidades.DeleteOne(c => c.Nome == "Roma");

...

Listagem 8: Excluindo um documento

Na Imagem 8 está o resultado após a exclusão realizada neste último passo.

mongo-08
Imagem 8. Coleção após a exclusão

Conclusão

Assim como outras soluções NoSQL, o MongoDB se destaca pela sua flexibilidade, compatibilidade com diversas plataformas de desenvolvimento e poder de processamento. Contudo, será necessário sempre se proceder com uma análise bem criteriosa quanto à adoção deste banco de dados. É importante ter em mente que o modelo relacional não perderá sua importância e, em muitos casos, ainda continuará a ser a alternativa mais adequada na implementação de novos projetos.

Espero que este post tenha sido útil.

Até uma próxima oportunidade!

Referências

Exemplo de utilização do MongoDB em uma aplicação .NET
https://gallery.technet.microsoft.com/Exemplo-de-utilizao-do-a3cb1f6c

Configuração do ambiente para MongoDB no Windows
https://pablojuancruz.wordpress.com/2014/09/03/configurando-ambiente-mongodb-no-windows/

FAQ: MongoDB Fundamentals
https://docs.mongodb.org/manual/faq/fundamentals/

The MongoDB Manual
https://docs.mongodb.org/manual/

Renato Groffe

Atua como consultor em atividades voltadas ao desenvolvimento de softwares há mais de 13 anos. Bacharel em Sistemas de Informação, com especialização em Engenharia de Software. Microsoft Certified Technology Specialist (Web, WCF, Distributed Applications, ADO.NET, Windows Forms), Microsoft Specialist (HTML5 with JavaScript and CSS3, Developing ASP.NET MVC 4 Web Applications), Oracle Certified Associate (PL/SQL), Sun Certified (SCJP, SCWCD), ITIL Foundation V2, Cobit 4.1 Foundation.

Facebook Google+ 

Comentários

comentarios