Um assunto que tem crescido bastante no último ano é o conceito de banco de dados NoSQL(Not only SQL), que a principio não diz o que é, apenas o que não é 🙂 . Basicamente o termo é utilizado em oposição ao pensamente da maioria dos desenvolvedores que se você tem que armazenar algum dado isso dever ser feito em um Banco de Dados Relacional(SQL).

Bancos de Dados Relacionais já foram a “bala de prata” mas nos dias de hoje os requisitos de uma performance superior e alta disponibilidade permitiram outros tipos de banco de dados que utilizam outras formas de organização de dados como Wide Column Store/Column Families, Document Store, Key Value/Tuple Store, Eventually Consistent Key Value StoreGraph DatabasesObject Databases, Grid Database SolutionsXML Databases.

Como tudo no mundo os bancos de dados NoSQL não fazem mágicas! Eles fornecem melhor performance/disponibilidade/escalabilidade mas para isso fazem alguns sacrifícios nos conceito de ACID.

Um bom podcast que saiu recentemente muito bom foi do Grok Podcast sobre NoSQL em geral

O MongoDB é um destes bancos que utiliza o modelo de armazenamento document-oriented  que armazena documentos no estilo parecido JSON chamado BSON. Veja um exemplo de JSON.

{
    nome : "Rodrigo",
    sobrenome : "Aramburu",
    telefone : ["1234-5678","9898-9898"],
    endereco : {
                rua : "Rua Fulano",
                numero : "221B",
                bairro : "Centro"
            } 
}

Para quem está acostumado a trabalhar com Banco de Dados Relacionais o MongoDB é uma boa quebra de paradigma já que ele não possui schema, ou seja não é necessário estipular a estrutura dos dados ao criar o banco, basta adicionar o documento(JSON) contendo os campos desejados, inclusive um documento pode conter outros documentos.

Primeiramente vamos baixar o MongoDB, basta descompactá-lo e executar o serviço:

$ bin/mongod

Por padrão os arquivos de armazenamento serão criados na pasta /data/db/ se houver necessidade de ser armazenado em outra pasta basta utiliza o parâmetro -dbpath

$ bin/mongod -dbpath banco

Com o serviço iniciado vamos brincar um pouco com o shell, basta iniciá-lo:

$ bin/mongo

Ele é um utilitário JavaScript que permite utilizar variáveis, laços, etc. Para ver os comando disponíveis basta utilizar o comando help, também é válido lembrar que o shell já vem com o banco “test” selecionado, então se você quiser trocar de banco deve utilizar o comando use nome_do_banco. Só lembrando para listar todos os banco de dados basta utilizar o comando show dbs

Os documentos no banco de dados no MongoDB são organizados em coleções(collections), uma coleção não exige que os documento armazenados nela tenham todos os mesmos campos, por exemplo, pode ser armazenado um documento de contato e de um carro em uma mesma coleção mesmo que não faça sentido nenhum fazer isso 🙂 . Para criar uma coleção podemos utilizar o comando abaixo:

db.createCollection( "nome_da_coleção" )

e para vermos todas as coleções de um banco de dados utilizamos o comando:

db.getCollectionNames()

Se você notou para criar e listar nossa coleções utilizamos o objeto db que é através dele que iremos manipular nossas coleções e documentos. Para ver todos os comando que podemos utilizar basta executar db.help() e db.nome_da_colecao.help().

Agora vamos inserir uma pessoa na coleção pessoas:

db.pessoas.save( { nome:"Rodrigo" , sobrenome:"Aramburu" } )

e agora vamos inserir uma pessoa com um telefone na mesma coleção:

db.pessoas.save( { nome:"João" , sobrenome:"Silva" , telefone:"1234-5678" } )

ou também podemos inserir uma pessoa com vários telefones fornecendo um array para o campo:

db.pessoas.save( { nome:"João" , sobrenome:"Silva" , telefone: [ "9898-9898" , "1234-5678" ] } )

Agora vamos listar as pessoas

db.pessoas.find()

Onde será listados todos os documento armazenados na coleção

{ "_id" : ObjectId("4e7fa9fa6ad8e47661dfff44"), "nome" : "Rodrigo", "sobrenome" : "Aramburu" }
{ "_id" : ObjectId("4e7fae3a6ad8e47661dfff45"), "nome" : "João", "sobrenome" : "Silva", "telefone" : "1234-5678" }
{ "_id" : ObjectId("4e7faeac6ad8e47661dfff46"), "nome" : "João", "sobrenome" : "Silva", "telefone" : [ "9898-9898", "1234-5678" ] }

Você deve ter notado o campo “_id” ele é um identificador único de um documento, se este campo não for informado quando o documento for salvo ele será gerado automaticamente.

Podemos filtrar a busca fornecendo um objeto, no caso vamos buscar por todas as pessoas com o nome Rodrigo

db.pessoas.find( { nome:"Rodrigo" } )

Como toda busca existem várias opções de filtragem podemos começar com os clássicos:

db.pessoas.find( { idade : { "$gt" : 18 } } ) //maior que 
db.pessoas.find( { idade : { "$lt" : 18 } } )//menor que 
db.pessoas.find( { idade : { "$gte" : 18 } } )//maior ou igual que
db.pessoas.find( { idade : { "$lte" : 18 } } )//menor ou igual que 
db.pessoas.find( { idade : { "$ne" : 18 } } )//diferent 

Um pouco diferente do que estamos acostumados. No objeto de pesquisa especificamos o campo que queremos fazer a comparação e atribuímos a ele um outro objeto que possui como campo a comparação queremos fazer e o valor.

Os operadores OU e E que são um pouco difícil de entender já que a posição parece mais estranha veja-os:

db.pessoas.find( { "$or": [ { nome:"Rodrigo" } , { nome:"João" } ] } )

Temos o objeto de pesquisa com o campo $or que recebe como valor um array e irá executar o operador OU para cara um destes valores. Também poderá ser utilizado juntamente com qualquer outra comparação como:

db.pessoas.find( { telefone:"1234-5678" , "$or": [ { nome:"Rodrigo" } , { nome:"João" } ] } )

Neste caso buscará todas as pessoas que tiverem o telefone “1234-5678” E o nome for “Rodrigo” OU “João”.

A operação AND pode ser feita de duas maneiras, se for com dois campos diferentes é bastante simples

db.pessoas.find( { nome:"Rodrigo" , sobrenome:"Aramburu"} )

Mas se tivermos utilizando o mesmo campo é necessário utilizar o formato abaixo(que apenas funciona na v2.0+):

db.pessoas.find( { "$and": [ { nome : { "$ne" : "Rodrigo" } } , { nome : { "$ne" : "João" } } ] } )

Também no caso de se estar tentando estipular um intervalo de valores também pode ser feio assim:

db.pessoas.find( { idade : { $gte : 18 , $lte : 29 } } ) 

Também para pesquisa temos o exists que buscas apenas os documentos que tem ou não tem um determinado campo (semelhante ao not null que conhecemos)

db.pessoas.find( { telefone : { $exists : true } } )
 
//ou
 
db.pessoas.find( { telefone :{ $exists : false } } )

E o in que busca todos os documentos em que o campo for igual a a qualquer um dos valores contidos no array

db.pessoas.find( { nome : { $in :[ "Rodrigo" , "fernando" ] } } )

Bom acho que era isso, mais você pode ver na documentação do MongoDB .

Devo publicar mais um post mostrando como conectar Java com MongoDB no dia randon().