Vous êtes sur la page 1sur 8

neo4j_

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

conceitos desse novo paradigma atravs de uma


adaptao do modelo de dados de um e-commerce.
Tambm ser mostrado como utilizar a API do Neo4j
para persistir e pesquisar as informaes no banco
de dados, utilizando desde a API Java at a poderosa
linguagem de pesquisas Cypher.

A modelagem atravs de grafos


Muitos desenvolvedores esto acostumados com
$+#2$.)""$+ )+0$ )'(1)0+2)'(.!$%('*+$% )+ )3%!0$"+
quais tabelas e colunas faro parte do nosso modelo
)+ ( $"4+5)3%!0$"+6(0&70+("+6(&)'("+)%8$'8! ("+)+
seus respectivos relacionamentos pensando em suas
cardinalidades, por exemplo. A modelagem nos consegue mostrar como as informaes so interligadas
em nosso modelo de negcio e como os dados esto
relacionados entre si.

Adriano Almeida | adriano.almeida@caelum.com.br


Trabalha como instrutor, consultor e desenvolvedor pela Caelum e formado em Sistemas de Informao pela FIAP. Desenvolve
aplicaes em Java desde 2005 e contribui com alguns projetos open sources, inclusive o banco de dados Neo4j

Para podermos nos aprofundar


nas caractersticas
dos
grafos e tambm na construo de
uma soluo que envolver o uso do banco de dados Neo4j, utilizaremos um domnio
de um e-commerce, onde clientes podero realizar compras de produtos categorizados por tipos,
podero indicar que outros clientes so seus amigos
e tambm quais produtos eles possuem interesse em
comprar no futuro, podendo indicar o nvel desses
interesses em uma escala de 1 a 5 (pouco interesse

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

Imagem 1. Grafo demonstrando diversos relacionamentos entre diferentes tipos de informaes.

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.

A instalao do Neo4j e a persistncia


dos primeiros dados
O primeiro passo para conseguirmos criar uma
aplicao que utilize o banco de dados Neo4j, realizarmos o seu download e instalao. O arquivo .zip
contendo todos os componentes necessrios para
utilizar o banco de dados pode ser encontrado em
http://neo4j.org/download/ onde possvel escolher o
arquivo mais adequado para cada tipo de ambiente.
Uma vez escolhido e baixado o pacote, basta descompactar o arquivo no seu sistema. Dentro da estrutura
de diretrios do pacote, todos os jars necessrios para
que o banco de dados funcione podem ser encontrados dentro da pasta lib. Pronto, com isso, podemos
criar um projeto em nossa IDE preferida, adicionando
os jars ao classpath de nossa aplicao. Note que o
processo extremamente simples e se o leitor quiser,
tambm possvel adicionar Neo4j em seu projeto
maven adicionando o cdigo da Listagem 1 ao seu arquivo pom.xml.

Listagem 1. !"#$%& #' $()&*+,-.& #& /'&01 2$,


maven.
<dependency>
<groupId>&*%34'&01</groupId>
<artifactId>4'&01</artifactId>
<version>1.5</version>t
</dependency

Com um projeto criado, podemos persistir nossa


primeira informao. No caso, ser um produto.

A criao do banco de dados

public static void main(String[] args) {


GraphDatabaseService db = new
EmbeddedGraphDatabase(/tmp/db);
db.shutdown();
}

9+!0#2)".!% :8)'+;<)+")0#2)+;<)+(+.2!(=>$+ )+<0+


objeto do tipo EmbeddedGraphDatabase, que representa um banco de dados do Neo4j, realizada, antes
de a aplicao terminar, o mesmo objeto seja corretamente fechado atravs da invocao do mtodo
shutdown(). Agora que j sabemos como um banco de
dados pode ser criado, podemos partir para a persistncia das informaes.

ACID e controle de transaes


Uma das principais caractersticas do Neo4j
manter um sistema transacional que respeita as to
conhecidas propriedades ACID, muito comuns em
bancos de dados relacionais, na qual dito que as
transaes devem ser atmicas, levar o banco de dados de um estado consistente a outro, manter o isolamento das transaes e cuidar da durabilidade dos
dados. Juntas, essas caractersticas formam um dos
principais pilares que sustentam os sistemas de bancos de dados relacionais.
Com o Neo4j, o ponto de entrada para trabalhar
com transaes a classe EmbeddedGraphDatabase,
(62(87"+ $+ ")<+ 076$ $+ &)1!%?-@A*+ )3%! $+ %(+ !%6)2face GraphDatabaseService, que retorna um objeto
do tipo Transaction. A partir do momento em que
o mtodo beginTx() invocado, todas as operaes
envolvendo o banco de dados, naquela Thread, considerado parte da transao, at o momento em que
o mtodo success() ou failure() sejam invocados na
0)"0(4+B$2+30*+(+62(%"(=>$+ )8)+")2+3%('!C( (+(62(87"+ $+076$ $+3%!"/@A4+D0+)-)0#'$+ )+<0+&'$.$+;<)+
.2!(+)+3%('!C(+("+62(%"(=E)"+ $+F)$GH+7+0$"62( $+%(+
Listagem 3.

A partir do momento em que temos as bibliotecas


do Neo4j, possvel criar o primeiro banco de dados,
para que seja possvel popul-lo.
Para isso, precisamos utilizar a API do prprio
Neo4j, simplesmente instanciando um objeto do tipo
EmbeddedGraphDatabase, que implementa a interface GraphDatabaseService, passando como parmetro Listagem 3. Abertura e fechamento de transaes
para seu construtor, uma String contendo o caminho 5&( & /'&013
no disco para onde o banco de dados estar armazenado. Um exemplo dessa instruo mostrado no c- public class PersisteProduto {
digo da Listagem 2, onde existe um mtodo main que
public static void main(String[] args) {
cria o banco de dados.
GraphDatabaseService db =
new EmbeddedGraphDatabase(/tmp/db);
Transaction tx = db.beginTx();

/ 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

Listagem 4. !*$, 6( 4&2& 4" ' #'74' ,8 )*&)*$'#,des.

O prximo passo realizar o relacionamento


das duas informaes, ou seja, relacionarmos os dois
ns que criamos previamente. Para tanto, precisaremos recuperar os dois ns do banco de dados. No
momento, podemos realizar essa tarefa, atravs de
uma simples busca pelo id no banco de dados, que
possvel atravs do mtodo getNodeById() da classe
System.out.println(Novo produto gravado com id: +
EmbeddedGraphDatabase. Uma vez com os dois obnoProduto.getId());
jetos Node, possvel criarmos um relacionamento
tx.success();
de um n para o outro, atravs do mtdo createRela} !"##$ {
tionshipTo() da classe Node, que precisa de dois patx. !%&'();
rmetros, o n de destino do relacionamento e o tipo
}
de relacionamento, respectivamente. O n de origem
7+ )3%! $+(62(87"+ $+%I+%$+;<('+$+076$ $+.2)(6)M)O mesmo processo pode ser aplicado para a cria- lationshipTo foi invocado. Considerando que o id do
o de uma categoria, cujo exemplo de cdigo mos- produto seja 1 e o id da categoria seja 2, o cdigo para
trado na Listagem 5 e com isso possvel realizar a criar o relacionamento ser equivalente ao da Listapersistncia dos primeiros ns no banco de dados.
gem 7.
Transaction tx = db.beginTx();
try {
Node noProduto = db.createNode();
noProduto.setProperty(nome, Playstation 3);
noProduto.setProperty(preco, 850.99);

Listagem 5. !*$, 6( 4&2& 4" ),*, 5,+'%&*$, ' #'74'


as propriedades.
Transaction tx = db.beginTx();
try {
Node noCategoria = db.createNode();
noCategoria.setProperty(nome, Video Game);
System.out.println(Nova categoria gravada com id: +
noCategoria.getId());
tx.success();
} !"##$ {
tx. !%&'();
}

/'&01 ' &8 $#8


Devido ao fato de o Neo4j reaproveitar os ids, ou
seja, quando um n excludo, o id passa a ser passvel de reaproveitamento para futuros ns, o uso
do mtodo getNodeById extremamente desencorajado. Em seu lugar, deve ser utilizado o mecanismo de indexao, que tambm apresentado neste
artigo.

21 \

Listagem 7. Relacionamento entre dois ns.


Transaction tx = db.beginTx();
try {
Node noProduto = db.getNodeById(1);
Node noCategoria = db.getNodeById(2);
Relationship r = noProduto.createRelationshipTo(
noCategoria, Relacionamentos.E_UM);
99 : )&88;2'< 5=,(,* & (>+&#& 8'+?*&)'*+@ ' #'74$*
// uma propriedade no relacionamento
tx.success();
} !"##$ {
tx. !%&'();
}

B$2+30*+(#I"+(+)-).<=>$+ ("+.'("")"*+<0+12(L$+"!milar ao da imagem 2 existir no banco de dados.

vs do mtodo index() em EmbeddedGraphDatabase.


Com o IndexManager, podemos invocar o mtodo
forNodes(), indicamos que queremos indexar ns
do nosso banco de dados, e recebe como parmetro
!" #$!% !&"%'($)!* +!,#)!$-$!+$. +"/!0#! 12$. !% !
tipo Index<Node>, que nos permite manipular o ndice, como mostrada na Listagem 8, que cria um ndice
para os produtos.

Listagem 8. Criao do ndice para os ns referentes


a produtos.
Transaction tx = db.beginTx();
try {
IndexManager index = db.index();
Index<Node> produtos = index.forNodes(produtos);
tx.success();
} !"##$ {
tx. !%&'();
}

Com o objeto do tipo Index<Node> em mos,


possvel adicionarmos informaes nele, para que
o Lucene realize a indexao. Para isso, basta invocarmos o mtodo add(), passando como parmetro o
n que ser indexado e um conjunto de chave e valor
*/+/!/!'"%$3/45 6!7.+/89:!%/!(;/8$)!* %$# :!'%$".',car a informao que ser indexada e o valor indica o
contedo que ser efetivamente indexado. Dessa maImagem 2. Relacionamento entre um produto e categoria.
neira, possvel indexar o primeiro produto j adicioA partir desse instante, o mesmo processo pode nado, primeiramente buscando-o no banco de dados
ser realizado para cadastrar todas as outras informa- (vamos realizar a busca atravs do id) e em seguida
es da aplicao, inclusive, representando o modelo indexando-o, como na Listagem 9.
inicial da imagem 1 no banco de dados.
Listagem 9. Indexao de um produto.

Indexao de informaes e pesquisas


simples
Conforme a aplicao vai ganhando mais e mais
dados e os ns vo sendo persistidos, pode surgir a
necessidade de realizar pesquisas, como, por exemplo, procurar o produto chamado Geladeira, ou ento, pesquisarmos a categoria DVD.
O Neo4j prov esse tipo de pesquisa atravs da
integrao com a biblioteca Lucene pelas classes
contidas no arquivo neo4j-lucene-index.jar, que se
encarregam de realizar o trabalho de indexao dos
dados. O prprio Lucene j vem distribudo com o
conjunto de jars do Neo4j, bastando utiliz-la.

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. !%&'();
}

Outra possibilidade o uso do mtodo query() ao


invs do mtodo get(), que permite a realizao de
pesquisas similares ao like do SQL. Nesse caso, para
pesquisar os produtos cuja primeira letra P, pode-se
fazer como na Listagem 11.

Listagem 11. Pesquisa de produto com wildcard.


Transaction tx = db.beginTx();
try {
IndexManager index = db.index();
Index<Node> produtos = index.forNodes(produtos);
IndexHits<Node> indexHits = produtos.query(nome,
P*);
for (Node node : indexHits) {
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

Listagem 12. Busca dos relacionamentos do produto.


IndexManager index = db.index();
Index<Node> produtos = index.forNodes(produtos);
IndexHits<Node> indexHits = produtos.get(nome,
Playstation 3);
Node noProduto = indexHits.getSingle();
Iterable<Relationship> relationships = noProduto.
getRelationships(Direction.OUTGOING,
Relacionamentos.E_UM);
for (Relationship rel : relationships) {
Node noCategoria = rel.getEndNode();
System.out.println(noCategoria.getProperty(nome));
}
tx.success();

Pesquisa de dados no grafo atravs dos


traversals
Algumas pesquisas tornam-se mais complicadas
de serem realizadas atravs da busca simples pelo
relacionamento, como, por exemplo, quando precisamos saber quais pessoas compram que produtos.
Nesse caso, tomando como ponto de partida um
cliente chamado Joo, primeiramente, precisamos
conhecer as compras realizadas por ele. Nesse instante, estamos no primeiro nvel de profundidade do
nosso processo de percorrer o grafo. Em seguida, j
que conhecemos as compras, podemos saber os produtos comprados por ele, o que nos leva ao segundo
nvel de profundidade da pesquisa.
O prximo passo sabermos de quais outras
compras eles fazem parte, o que nos leva ao terceiro
"&8$-!%$!*+ @0"%'%/%$6!A)!* +!,#)!2B!:/1$"% !/:!( #*+/:! C0$! $::$:! *+ %0. :! ,D$+/#! */+.$)! .$# :! ( # !
descobrir os outros produtos que fazem parte dessas
compras. Repare que temos que realizar uma pesquisa em um alto nvel de profundidade do nosso grafo,
o que no necessariamente uma pesquisa simples
de ser feita em um banco de dados relacional, mas
totalmente passvel de ser realizada.

23 \

Note que para tanto precisamos percorrer o grafo


atrs dessas informaes, o que um processo conhecido como Traversal.
O Neo4j permite a realizao de traverses no grafo atravs da classe TraversalDescription, que faz o
papel de um builder para um processo de traverse. No
caso, precisamos indicar quais relacionamentos devem ser percorridos e de qual profundidade os dados
ns devero ser devolvidos. Dessa forma, para realizarmos a pesquisa descrita anteriormente, teremos
um cdigo similar ao da Listagem 13.

Listagem 13. Descrio e realizao de um processo


de traverse.
TraversalDescription td = Traversal.description()
.breadthFirst().relationships(Relacionamentos.
REALIZOU, Direction.OUTGOING)
.relationships(Relacionamentos.
CONTEM, Direction.OUTGOING)
.relationships(Relacionamentos.
CONTEM, Direction.INCOMING)
.relationships(Relacionamentos.
CONTEM, Direction.OUTGOING)
.evaluator(Evaluators.atDepth(4));
Node noInicial = db.getNodeById(42);
Iterable<Node> traverse = td.traverse(noInicial).nodes();
for (Node node : traverse) {
System.out.println(node);
}

Realizao de pesquisas com a query


language Cypher

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.

Listagem 16. Pesquisa complexa com Cypher.


start n=node(42) match (n)-[:REALIZOU]->(compras)[:CONTEM]->(produtosComprados)<-[:CONTEM](outrasCompras)-[:CONTEM]->(outrosProdutos) return
outrosProdutos
Note que na pesquisa indicado atravs de caracteres como as setas para direita e esquerda se os relacionamentos so de chegada ou sada em um determinado n. No caso dessa pesquisa, possvel ler a
clusula match como: onde n realizou compras que
continham produtosComprados que estavam em outrasCompras que por sua vez continham outrosProdutos.
Para realizarmos a consulta dentro da aplicao
Java, necessrio criar uma instncia de ExecutionEngine, passando o db como parmetro, em seguida, invocando o mtodo execute no objeto criado,
passando a String da consulta como parmetro, como
$3$#*-',(/% !"/!<':./=$#!>G)! "%$! !+$:0-./% !./#bm pego atravs do Iterator retornado, e exibido
na console.

Apesar do poder existente na escrita de traversals


atravs da API do Neo4j, muitos desenvolvedores no
se sentem confortveis escrevendo suas consultas em
cdigo Java, o que algo totalmente compreensvel.
Alm disso, a escrita de consulta em cdigo Java pode
atrapalhar tambm o processo de operaes, no qual,
administradores de banco de dados precisam manipular os dados existentes no banco. Justamente para
satisfazer os diversos gostos, o Neo4j possui tambm
uma linguagem de consulta que permite pesquisar
informaes dentro dos grafos, no caso, o Cypher.
Listagem 17. Pesquisa complexa com Cypher dentro
Uma simples query com o Cypher para buscar um de cdigo Java.
n no banco de dados atravs de seu id pode ser escrita em poucos caracteres, como visto na Listagem 14.
ExecutionEngine engine = new ExecutionEngine(db);

Listagem 14. Query simples com o Cypher.


start n=node(1) return n
Na pesquisa, indicamos que queremos buscar um n,
cujo id 1 e ele dever ser retornado pela pesquisa.
/ 24

ExecutionResult result = engine


.execute(start n=node(9) match (n)-[:REALIZOU]>(compras)-[:CONTEM]->(produtosComprados)<[:CONTEM]-(outrasCompras)-[:CONTEM]>(outrosProdutos) return outrosProdutos);

Iterator<Node> results = result.


columnAs(outrosProdutos);
while(results.hasNext()) {
Node no = results.next();
System.out.println(no.getProperty(nome));
}

F +! ,#)! /! -'"=0/=$#! HI*;$+! *$+#'.$!


que se utilize recursos muito
comuns aos bancos de dados relacionais e ao SQL, como group
by, funes de agregao como
SUM e AVG, clusulas where caso haja a necessidade de
,-.+/+! /! *$:C0':/! *$- ! 8/- +! %$!
alguma propriedade de um n e assim por diante.

Ferramentas auxiliares, o Neo4j Server e


escalabilidade
Alm de toda a parte da persistncia, o Neo4j possui ferramentas perifricas, que permitem a administrao do banco de dados, como o Neo4j Shell, que
uma aplicao que possibilita a manipulao do banco de dados atravs do terminal.
Para usurios que preferem uma visualizao gr,(/)!* %$J:$!0.'-'D/+!./#19#!/!@$++/#$"./!K$ (-'*:$)!
onde possvel visualizar os ns e relacionamentos
do banco de dados, consultar ndices, e manipular as
informaes com poucos cliques. O Neoclipse, por padro, no vem com o pacote do Neo4j, mas pode ser
baixado em separado na prpria pgina de downloads
do projeto.
Outro ponto importante que no decorrer deste
artigo foi mostrado o Neo4j embedded, no qual o desenvolvedor simplesmente adiciona o jar ao seu projeto e utiliza-o como se fosse apenas mais uma biblioteca em seu projeto. No entanto, caso seja necessrio
utilizar o Neo4j em outras plataformas, que no Java,
a distribuio vem com uma verso server, que inicia-'D/!0#!:$+8'% +!% !K$ L2!C0$!,(/!%':* "&8$-!*/+/!:$+!
manipulado via chamadas REST, permitindo assim o
uso do banco de dados com outras plataformas que
no Java. O Neo4j Server tambm vem com uma interface web de administrao, onde possvel manipular
e administrar os dados on-line.
F +!,#)!9!'#* +./".$!+$::/-./+!C0$! !K$ L2!* %$!
suportar at bilhes de ns e relacionamentos armazenados em seu banco de dados e, ainda assim, atingir
alta performance ao percorrer grafos, tudo possvel ao
modelo de dados e armazenamento interno otimizado para esse tipo de operao.

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 \

Vous aimerez peut-être aussi