ArangoDB

ArangoDB

Já escrevi sobre o ArangoDB nesse blog, trata-se de um banco NoSQL multi-paradigma, sendo possível trabalhar com orientação a documentos, chave/valor e grafos.

Esse post é uma pequena amostra do que o ArangoDB pode fazer e quais suas diferenças comparando com outros NoSQL (como o MongoDB, por exemplo). Como estou utilizando ArangoDB em prova de conceito em alguns projetos, vou escrever mais posts sobre esse banco. Minha opinião pessoal até então é bastante impressionante! O banco atende bem, possui boas features e uma comunidade crescente.

Diferente do MongoDB, o ArangoDB exige que as bases e as coleções sejam criadas antes de começar a inserir documentos. Como exemplo, vou criar uma base chamada musica e duas coleções: usuarios e bandas. Depois vamos relacionar, através de arestas, quais são as bandas que cada usuário ouve.

O arango shell

Depois do ArangoDB instalado e inicializado, vamos entrar no seu shell via o seguinte comando:

arangosh

Criando e acessando a base musica

Como já foi explicado, é necessário criar a base antes de começar a inserir documentos.

arangosh [_system]> db._createDatabase('musica')

Depois é necessário acessar a base através de:

arangosh [_system]> db._useDatabase('musica')
true

O retorno “true” na segunda linha significa que a base existe e foi acessada com sucesso. Caso receba algum erro, verifique se criou a base corretamente.

Criando as coleções

Também é necessário criar as coleções, que podem ter diferentes atributos: Coleção de Documento e Coleção de Edges, utilizada para grafos. Neste exemplo, duas coleções de documentos serão criadas:

arangosh [musica]> db._createDocumentCollection('usuarios')
[ArangoCollection 3466539644, "usuarios" (type document, status loaded)]

Em seguida, criando a coleção de bandas:

arangosh [musica]> db._createDocumentCollection('bandas')

Agora é hora de popular o banco, nesse exemplo vou cadastrar 5 usuários como abaixo:

db.usuarios.insert({
...> 'nome':'Christiano Anderson',
...> 'cidade':'Porto Alegre',
...> 'uf':'RS'})

Repito o processo acima para outros 4 usuários e temos:

arangosh [musica]> db.usuarios.toArray()
[ 
  { 
    "uf" : "MG", 
    "nome" : "Vanessa Silva", 
    "cidade" : "Belo Horizonte", 
    "_id" : "usuarios/22954366064", 
    "_rev" : "22954366064", 
    "_key" : "22954366064" 
  }, 
  { 
    "uf" : "RJ", 
    "nome" : "Patricia Santos", 
    "cidade" : "Rio de Janeiro", 
    "_id" : "usuarios/22806254704", 
    "_rev" : "22806254704", 
    "_key" : "22806254704" 
  }, 
  { 
    "uf" : "RS", 
    "nome" : "Christiano Anderson", 
    "cidade" : "Porto Alegre", 
    "_id" : "usuarios/22803567728", 
    "_rev" : "22803567728", 
    "_key" : "22803567728" 
  }, 
  { 
    "uf" : "SP", 
    "nome" : "Juliano Cardoso", 
    "cidade" : "Sao Paulo", 
    "_id" : "usuarios/22805140592", 
    "_rev" : "22805140592", 
    "_key" : "22805140592" 
  }, 
  { 
    "uf" : "PR", 
    "nome" : "Paulo Sampaio", 
    "cidade" : "Curitiba", 
    "_id" : "usuarios/22951089264", 
    "_rev" : "22951089264", 
    "_key" : "22951089264" 
  } 
]
Agora vamos popular a coleção de bandas, um total de 10 serão cadastradas:
db.bandas.insert({
...> 'nome':'Queen',
...> 'genero':'Rock',
...> 'pais':'Inglaterra'})

E cadastrando mais 9 bandas, teremos esse resultado:

db.bandas.toArray()
[ 
  { 
    "genero" : "Rock", 
    "pais" : "Brasil", 
    "nome" : "Paralamas do Sucesso", 
    "_id" : "bandas/22983136368", 
    "_rev" : "22983136368", 
    "_key" : "22983136368" 
  }, 
  { 
    "genero" : "Reggae", 
    "nome" : "Bob Marley", 
    "pais" : "Jamaica", 
    "_id" : "bandas/22985626736", 
    "_rev" : "22985626736", 
    "_key" : "22985626736" 
  }, 
  { 
    "nome" : "Kraftwerk", 
    "genero" : "Eletrônica", 
    "pais" : "Alemanha", 
    "_id" : "bandas/22988379248", 
    "_rev" : "22988379248", 
    "_key" : "22988379248" 
  }, 
  { 
    "genero" : "Rock", 
    "nome" : "Jethro Tull", 
    "pais" : "Inglaterra", 
    "_id" : "bandas/22994080880", 
    "_rev" : "22994080880", 
    "_key" : "22994080880" 
  }, 
  { 
    "pais" : "EUA", 
    "nome" : "Information Society", 
    "genero" : "Eletrônica", 
    "_id" : "bandas/22987265136", 
    "_rev" : "22987265136", 
    "_key" : "22987265136" 
  }, 
  { 
    "genero" : "Rock", 
    "nome" : "Led Zeppelin", 
    "pais" : "Inglaterra", 
    "_id" : "bandas/22979859568", 
    "_rev" : "22979859568", 
    "_key" : "22979859568" 
  }, 
  { 
    "genero" : "Soul", 
    "pais" : "EUA", 
    "nome" : "Aretha Franklin", 
    "_id" : "bandas/22990410864", 
    "_rev" : "22990410864", 
    "_key" : "22990410864" 
  }, 
  { 
    "nome" : "Sigur Rós", 
    "genero" : "Post Rock", 
    "pais" : "Islândia", 
    "_id" : "bandas/22982415472", 
    "_rev" : "22982415472", 
    "_key" : "22982415472" 
  }, 
  { 
    "nome" : "Queen", 
    "genero" : "Rock", 
    "pais" : "Inglaterra", 
    "_id" : "bandas/22976386160", 
    "_rev" : "22976386160", 
    "_key" : "22976386160" 
  }, 
  { 
    "genero" : "Rock", 
    "nome" : "The Beatles", 
    "pais" : "Inglaterra", 
    "_id" : "bandas/22991983728", 
    "_rev" : "22991983728", 
    "_key" : "22991983728" 
  } 
]

Exemplo de consulta

As consultas via shell no ArangoDB podem ser feitas com o método ByExample:

db.bandas.byExample({'genero':'Rock'}).toArray()

Criando associação entre os documentos

Agora que fica interessante, vamos criar uma coleção especial chamada edge collection que permite usar as arestas ou apontamentos com os devidos atributos. Essa coleção especial será chamada de gosto_musical e simplesmente vai associar se usuário gosta ou não gosta de determinada banda.

O primeiro passo é criar a coleção especial:

db._createEdgeCollection('gosto_musical')

Agora podemos popular essa coleção. O documento precisa ter um formato especial, basicamente elegemos a coleção de origem (nesse caso, a de usuários), a de destino (bandas) e uma etiqueta associando essa relação, nesse caso queremos algo do tipo Christiano Anderson –ouve–> Queen.

A associação funciona através da chave de cada documento, que é o campo _id dos dois lados. Então eu preciso pegar o _id do usuário mais o _id da banda e criar uma aresta associando os dois. Podemos facilitar isso via consulta, projetando o _id como resultado (exatamente como usei abaixo):

db.gosto_musical.save( db.usuarios.firstExample({'nome':'Christiano Anderson'})._id, db.bandas.firstExample({'nome':'Queen'})._id, {'label':'ouve'})

Essa associação pode ter outros valores, como “não gosta”, “adora”, “detesta”, etc. Com isso, é possível criar qualificadores dessa associação:

db.gosto_musical.save( db.usuarios.firstExample({'nome':'Vanessa Silva'})._id, db.bandas.firstExample({'nome':'Bob Marley'})._id, {'label':'não gosta'})

No exemplo acima informamos que a usuária Vanessa não gosta de Bob Marley.

Visualizando os grafos via interface web

O ArangoDB oferece uma ótima ferramenta web para gerenciar o banco, realizar CRUDs e visualizar associações com grafos. O acesso é feito via http://localhost:8529 e a interface é bastante amigável. Abaixo, temos a representação gráfica dos usuários da base acima e a ligação com as bandas que gosta ou não gosta.

ArangoDB Grafo Exemplo

ArangoDB Grafo Exemplo

 

O banco é bastante flexível, permite fazer muitas coisas unindo o melhor do paradigma de documentos com o paradigma de grafos. Tenho usado ArangoDB há vários meses e bastante satisfeito com o desempenho e suas features. Nos próximos posts, vou mostrar outras funcionalidades desse banco!