Académique Documents
Professionnel Documents
Culture Documents
Neo4j
na prtica
Como entrar no mundo dos bancos
de dados de grafo
O mundo dos bancos de dados
no-relacionais (NoSQL) cada vez
mais tem ganhado reconhecimento
do mercado, inclusive com grandes empresas adotando alguma das solues disponveis ou patrocinando o desenvolvimento das j existentes.
Nesse cenrio, ganhando grande ateno no mercado
internacional e baseado em uma das mais antigas teorias matemticas, o banco de dados Neo4j, implementado em Java, traz os grafos ao cenrio da persistncia de dados, de uma maneira que pode
!"#$!%&'()') *$+,-*)./)#(*0$/"' )1-*23(!4!'! )/")0'1&* )./).'.* )
relacionais ou at mesmo como uma boa alternativa tradicional
modelagem relacional.
adoo de um banco de dados no-relacional
geralmente passa por alguns fatores bastante
comuns, como necessidade de alta escalabilidade e
!"#$%!&!'! ( )*+,)-!&!'! ( )+ )+"./)0(+)+1(%/$"+ )+
performance. O banco de dados Neo4j pode prover
todos esses recursos s aplicaes, aliando a elas um
modelo rico de dados, baseado em grafos, permitindo a criao de modelos de dados extremamente
complexos e, ainda assim, mantendo uma considervel facilidade em pesquisar dados e adicionando a
tudo isso caractersticas que tornaram os bancos de
dados relacionais ferramentas to reconhecidas no
mercado, como transaes ACID e uma linguagem
simples para realizar pesquisa de dados.
Neste artigo o leitor aprender como modelar
suas aplicaes dentro desse novo paradigma que
a modelagem via grafos, e ser introduzido aos
/ 18
um
CALL OF
DUTY
e
ss
re
te
um
JOGO
FIFA 12
o
contend
te 4
in VEL
N
at muito interesse).
Um exemplo de um grafo possvel pode ser visto
na imagem 1.
Em nosso caso, indicamos que uma pessoa possui interesse em alguns produtos. Os produtos,
por sua vez, possuem uma relao com sua categoria. A partir do momento em que o cliente realiza uma compra, tambm passa a existir um relacionamento entre o cliente e a compra, que pode
possuir vrios produtos associados a ela. Os clientes
podem possuir amizade com outros clientes.
No grafo, alguns pontos so importantes de serem notados. Os ns so representados pelos crculos e podem possuir propriedades. Enquanto os relacionamentos so representados pelas setas, que so
sempre direcionadas, ou seja, possui um n de sada
e um n de chegada, como, por exemplo, o cliente
que possui um relacionamento INTERESSE com
um produto. Os relacionamentos podem possuir
propriedades tambm, como, por exemplo, o nvel
de interesse, que mediremos em um ranking de 1 a
5 estrelas.
9+!0#$26(%6:""!0$+8)2!3.(2+6(0&70+;<)+)0+%)%/<0+ 0$0)%6$+ )3%!0$"+ ./(8)"+ )"62(%1)!2("+ )0+
nosso modelo. Essa uma caracterstica vital na modelagem atravs de grafos, onde os dados se relacionam de forma natural, ou seja, atravs de seu papel
no domnio, sem a necessidade da criao de uma
)"62<6<2(+)"#).:3.(+#(2(+6('4
realizou
compra
ADRIANO
DATA
12.02.2010
contendo
PLAYSTATION 3
u
m
ig
am
o
de
RICARDO
realizou
compra
DATA
14.07.2010
contendo
um
VIDEO
GAME
XBOX 360
19 \
Com isso, temos o nosso grafo modelado e j co- Listagem 2. Classe que cria o banco de dados em um
nhecemos suas estruturas. No entanto, ainda preci- diretrio.
samos dar vida nossa modelagem no banco de dapublic class CriaBanco {
dos Neo4j.
/ 20
Gravao de relacionamentos
K)1<!% $+(+ )3%!=>$+ $+%$""$+ $0:%!$+)+(+0$delagem realizada no comeo do artigo, necessrio
relacionarmos os produtos com suas categorias. No
nosso caso, podemos dizer que o Playstation 3 um
tx.success();
videogame, logo, precisamos representar o relaciona} !"##$ {
mento um em nossa aplicao. Uma das maneiras
tx. !%&'();
}
)+ )3%!20$"+ $+ 2)'(.!$%(0)%6$+ )+ <0(+ L$20(+ ;<)+
db.shutdown();
no se baseie em Strings e seja type safe, criarmos
}
uma Enum que implemente a interface Relationship}
Type que uma interface de marcao do Neo4j, ou
seja, no possui mtodos para ser implementados.
Criao do primeiro produto e categoria
A partir do momento em que j possvel traba- Dessa maneira, podemos ter uma Enum chamada Relhar com transaes com o Neo4j, est tudo pronto lacionamentos, contendo o elemento E_UM, como na
para realizar a gravao de um n para o produto no Listagem 6.
banco de dados. Para isso, basta invocarmos o mto- Listagem 6. Enum que representa o relacionamento.
do createNode() da classe EmbeddedGraphDatabase,
que devolve um objeto do tipo Node, no qual poss8)'+ )3%!2+"<("+#2$#2!) ( )"4+F$+.("$+ )+<0+%$8$+%I+ public enum Relacionamentos implements
RelationshipType {
#(2(+$+#2$ <6$*+$+.I !1$+ (+62(%"(=>$+3.(2J+"!0!'(2+
E_UM;
ao da Listagem 4.
}
try {
// operaes dentro da transao vo aqui
21 \
Indexao de informaes
Para que seja possvel realizar as pesquisas, primeiramente, necessrio indexar as informaes. Na
API do Neo4j, a classe responsvel por ser o ponto
de entrada para o processo de indexao a IndexManager, da qual conseguimos uma instncia atra-
/ 22
Transaction tx = db.beginTx();
try {
IndexManager index = db.index();
Index<Node> produtos = index.forNodes(produtos);
Node noProduto = db.getNodeById(1);
produtos.add(noProduto, nome,
noProduto.getProperty(nome));
tx.success();
} !"##$ {
tx. !%&'();
}
!"#$%"&'()*!)+!,-.$,",)"/0"12,)*()3.4!5!)
A partir do momento em que os ns esto indexados, possvel pesquis-los atravs da API do Neo4j.
Para tanto, possvel utilizar o mtodo get() da classe
Index que devolve um objeto do tipo IndexHits, que
um objeto Iterable, contendo os ns devolvidos pela
pesquisa, alm de possuir alguns mtodos utilitrios,
como o getSingle(), que devolve apenas um elemento,
caso a pesquisa devolva somente um resultado. A ite- qual o relacionamento que se deseja buscar e a direrao sobre o IndexHits para mostrar o nome do pro- o do relacionamento com relao ao n. No caso do
duto no banco de dados mostrada na Listagem 10. exemplo, no produto, desejamos todos os relacionamentos E_UM que sejam de sada do produto, ou seja,
Listagem 10.)6!,-.$,")*!)+0(*./()"/0"12,)*()75*$4!8 OUTGOING. A invocao ao mtodo getRelationships
devolve um Iterable<Relationship>, com o qual podeTransaction tx = db.beginTx();
mos percorrer todos os relacionamentos. Os objetos
try {
do tipo Relationship, possuem mtodos chamados
IndexManager index = db.index();
Index<Node> produtos = index.forNodes(produtos);
getStartNode() e getEndNode(), que permitem descobrir os ns envolvidos no relacionamento. No caso,
IndexHits<Node> indexHits = produtos.get(nome,
podemos utilizar essas classes em conjunto para
Playstation 3);
buscar as categorias do produto Playstation 3, como
for (Node node : indexHits) {
$3$#*-',(/% !"/!<':./=$#!>?6
System.out.println(node.getProperty(nome));
}
tx.success();
} !"##$ {
tx. !%&'();
}
Alm da possibilidade de realizar pesquisas exatas e tambm similares ao like, como no caso das Listagens 10 e 11, o Neo4j tambm permite, atravs do
uso do Lucene, a realizao de pesquisas full-text.
6!,-.$,",)"/0"12,)*!)0!#"4$(5"9!5/(,
Apesar de a pesquisa atravs do ndice permitir
retornar as informaes do banco de dados, muitas
das vezes necessrio conhecer as adjacncias de um
n, como, por exemplo, para saber as categorias de
um determinado produto. Nesse caso, possvel simplesmente invocar o mtodo getRelationships(), que
possui vrias sobrecargas, inclusive uma que recebe
23 \
No entanto, podemos facilmente evoluir essa pesquisa para realizar tarefas mais complexas, como, por
exemplo, pesquisar atravs de algum ndice, o que
$3$#*-',(/% !"/!<':./=$#!>E)!/ !# :.+/+!( # !10:car a categoria videogame atravs de seu ndice.
Listagem 15.):.!0;)+(0)75*$4!)"/0"12,)*()<;+=!08
start n=node:categorias(nome=Video Game) return
n
Apesar de demonstrar a sintaxe de uma query Cypher,
/:! %0/:! *$:C0':/:! /('#/! "5 ! $3$#*-',(/#! . % ! !
poder da linguagem de pesquisas, por realizarem
pesquisas muito simples. Em nosso caso, desejamos
transformar a mesma pesquisa que escrevemos com a
API de Traversals, com o Neo4j.
F/+/! +$/-'D/+! *$:C0':/:! C0$! :5 ! %$,"'%/:! /.+/vs de caminhos no grafo, necessrio adicionar a
clusula match pesquisa, indicando quais relacionamentos sero trabalhados na pesquisa e em quais
sentidos, como na Listagem 16.
o
e praticamen.$!D$+ !( ",=0+/45 6!M$:sa maneira, extremamente
simples iniciar seu uso e avali-lo.
Sua API descomplicada facilita a adaptao para desenvolvedores que no estejam to familiarizados com o uso de bancos de
dados no-relacionais.
A realizao de consultas tambm outro ponto
que merece destaque, permitindo consultas complexas com poucas linhas de cdigo, caso seja feita atravs da API Java, ou de maneira expressiva, como se
tivesse desenhando o caminho de um grafo, atravs
da linguagem Cypher.
A maneira diferente de modelar as informaes
um ponto que pode causar bastante estranheza no
comeo, como um dia a modelagem relacional tambm causou nos desenvolvedores, mas com o hbito,
tende a se tornar algo natural.
/referncias
!"#$%&!'!())*+,,-#$%&.$/0
!"#$%&!1$2-3$456!'!())*+,,-#$%&.$/0,5$2-3$45
!73$0!"#$%&!'!())*+,,83$0.-#$%&.$/0
!9:*(#/;6!<-)#/-43!'!())*+,,4(43=#<54.>$=
!?/)<0$!6$8/#!$!"#$%&!-$!@-A$B!'!())*+,,222.<-A$B.>$=,
articles/graph-nosql-neo4j
!?*/#6#-)4CD$!6$8/#!$!"#$%&!'!())*+,,222.<-A$B.>$=,
presentations/emil-eifrem-neo4j
()!&%*+,"-.+&/ !"%&
O Neo4j um banco de dados de simples instala25 \