Você está na página 1de 100

UNIVERSIDADE FEDERAL DE SANTA MARIA

CENTRO DE TECNOLOGIA
CURSO DE CINCIA DA COMPUTAO

ANLISE DE BANCOS DE DADOS NOSQL E


DESENVOLVIMENTO DE UMA APLICAO

TRABALHO DE GRADUAO

Ivan Isaas Friess

Santa Maria, RS, Brasil


2013

ANLISE DE BANCOS DE DADOS NOSQL E


DESENVOLVIMENTO DE UMA APLICAO

por

Ivan Isaas Friess

Trabalho de Graduao apresentado ao Curso de Cincia da Computao


da Universidade Federal de Santa Maria (UFSM, RS), como requisito
parcial para a obteno do grau de
Bacharel em Cincia da Computao

Orientador: Prof Dr Deise de Brum Saccol

Trabalho de Graduao N 352


Santa Maria, RS, Brasil
2013

Universidade Federal de Santa Maria


Centro de Tecnologia
Curso de Cincia da Computao

A Comisso Examinadora, abaixo assinada,


aprova o Trabalho de Graduao

ANLISE DE BANCOS DE DADOS NOSQL E


DESENVOLVIMENTO DE UMA APLICAO

elaborado por
Ivan Isaas Friess
como requisito parcial para obteno do grau de
Bacharel em Cincia da Computao
COMISSO EXAMINADORA:

Prof Dr Deise de Brum Saccol


(Presidente/Orientador)
Prof Dr Eduardo Kessler Piveta (UFSM)
Prof Dr Marcia Pasin (UFSM)

Santa Maria, 20 de fevereiro de 2013.

AGRADECIMENTOS

Gostaria de agradecer, em primeiro lugar, minha famlia pelo incentivo de sempre.


Em especial aos meus pais, pelo apoio, fora e dedicao.
Agradeo professora Deise pela orientao deste trabalho. banca avaliadora,
professor Eduardo e professora Marcia, pelas sugestes de melhorias.
Tambm agradeo ao Centro de Processamento de Dados (CPD) da UFSM pela
chance de realizar um estgio e, em especial, ao colegas do setor de Diviso de Redes e
Sistemas Bsicos, pelos ensinamentos e o timo ambiente de trabalho.
No poderia deixar de agradecer Universidad Nacional del Este (UNE) pela
oportunidade que me foi dada de realizar um intercmbio, Facultad Politcnica (FPUNE)
pela excelente receptividade que tive. todas as pessoas que pude conhecer e conviver
durante o perodo de experincia no Paraguai.
Enfim, agradeo a todas as pessoas que, de alguma forma, contriburam para que este
momento tenha chegado.

Nossa maior fraqueza est em desistir.


O caminho mais certo de vencer tentar mais uma vez.
THOMAS EDISON

RESUMO

Trabalho de Graduao
Curso de Cincia da Computao
Universidade Federal de Santa Maria
ANLISE DE BANCOS DE DADOS NOSQL E
DESENVOLVIMENTO DE UMA APLICAO
Autor: Ivan Isaas Friess
Orientador: Prof Dr Deise de Brum Saccol
Local e data da defesa: Santa Maria, 20 de fevereiro de 2013.

Os bancos de dados NoSQL esto tornando-se cada vez mais conhecidos e utilizados
nos ltimos anos, em razo da necessidade de armazenamento de grande quantidade de
dados com os quais as organizaes tm que trabalhar e tambm do aumento de usurios
dos sistemas. Os bancos de dados tradicionalmente utilizados, como os relacionais,
apresentam fatores limitantes devido ao fato de no apresentarem muita flexibilidade na
estruturao dos dados. Com isto, os Bancos de Dados NoSQL so uma alternativa que
objetiva suprir estas e outras deficincias, como as questes de escalabilidade e
disponibilidade do sistema.
No entanto, os Bancos de Dados NoSQL so recentes e ainda pouco conhecidos, o
que poder ser um empecilho no momento de escolher um destes para gerenciamento de uma
base de dados. Assim, o objetivo deste trabalho realizar uma pesquisa, selecionando
alguns bancos de dados NoSQL e compar-los entre si, mostrando as funcionalidades
comuns e as particulares. Aps a comparao, escolhido um Banco de Dados NoSQL, de
acordo com as caractersticas de funcionamento, para o desenvolvimento de uma aplicao,
que utilizar o prprio banco de dados NoSQL para a realizao de consultas e
modificaes de sua base de dados, proporcionando assim um melhor entendimento sobre
esta tecnologia.

Palavras-chave: NoSQL, Banco de Dados.

ABSTRACT

Undergraduate Final Work


Undergraduate Program in Computer Science
Federal University of Santa Maria
NOSQL DATABASES ANALYSIS AND
DEVELOPMENT OF AN APPLICATION
Author: Ivan Isaas Friess
Advisor: Prof Dr Deise de Brum Saccol

NoSQL databases are becoming more popular and more used in recent years, mainly
due to the large amount of data that organizations have to deal with and to the increasing
number of system users. Databases commonly used have limiting factors such as the lack of
flexibility in structuring data. Thus, NoSQL databases are an alternative that aims to
overcome deficiencies like scalability and availability.
However, NoSQL databases are recent and practically unknown; choose one of these
management systems can be an obstacle for managing a database. The goal of this work is to
perform a search by selecting and comparing some NoSQL databases, pointing out the
common and the particular features. After the comparison, one NoSQL database is chosen
according to some features, in order to develop an application that uses the NoSQL database
to pose queries and updates over the data, allowing a better understanding of this technology.

Keywords: NoSQL, databases.

LISTA DE FIGURAS
Figura 2.1: Exemplo documento JSON (Wikipedia, 2012) ...................................................18
Figura 2.2: Arquitetura Redis (Campanelli, 2011). ................................................................20
Figura 2.3: Modelo de Cluster no Riak (Riak, 2012). ............................................................23
Figura 2.4: Cluster do Cassandra (Cassandra, 2012) .............................................................26
Figura 2.5: Modelo de dados do Apache Cassandra ( Cho, 2010) .........................................27
Figura 2.6: Repositrio do Apache Cassandra ........................................................................28
Figura 2.7: Chave Publica do repositrio ...............................................................................28
Figura 2.8: Instalao do Apache Cassandra ..........................................................................28
Figura 2.9: Arquitetura HBase ................................................................................................31
Figura 2.10: Arquitetura CouchDB .........................................................................................33
Figura 2.11: Arquitetura Cluster MongoDB (Orend, 2010). ..................................................36
Figura 2.12: Modelo de dados no Neo4j (Neo4j, 2012). ........................................................40
Figura 3.1: Modelo documento dos metadados ......................................................................45
Figura 3.2: Documento inserido na coleo "files", incluindo metadados ............................45
Figura 3.3: Modelo documento na coleo "chunks" .............................................................46
Figura 3.4: Diagrama de caso de uso da aplicao .................................................................46
Figura 4.1: Diagrama de classes da aplicao ........................................................................50
Figura 4.2: Cdigo do mtodo conectar...................................................................................51
Figura 4.3: Trecho do cdigo do mtodo formataConsulta ....................................................51
Figura 4.4: Cdigo do mtodo consultaBanco .......................................................................52
Figura 4.5: Cdigo do mtodo excluir.....................................................................................52
Figura 4.6: Cdigo do mtodo insereDoc ...............................................................................53
Figura 4.7: Cdigo do mtodo editarMetadados ....................................................................54
Figura 4.8: Tela principal Usurio Cliente .............................................................................56
Figura 4.9: Tela de Autenticao como Administrador ..........................................................56
Figura 4.10: Tela de Visualizao dos Detalhes .....................................................................57
Figura 4.11: Tela principal do Administrador .........................................................................59
Figura 4.12: Tela de Insero de Monografias .......................................................................60
Figura 4.13: Documento gerado na insero da monografia .................................................61
Figura 4.14: Caixa de texto para consulta avanada ..............................................................62
Figura 4.15: Tela de Edio de Monografias. .........................................................................65

LISTA DE TABELAS

Tabela 2.1: Tabela comparativa NoSQL Databases.................................................................42


Tabela 4.1: Carga de inseres na base dados...........................................................................67

LISTA DE APNDICES

APNDICE A Cdigo fonte da aplicao............................................................................74


A.1 BuscaDocumento.java....................................................................................................74
A.2 BuscaDocAdm.java........................................................................................................81
A.3 NovoDocumento.java.....................................................................................................88
A.4 EditarDocumento.java....................................................................................................94
A.5 VisualizarDocumento.java.............................................................................................97
A.6 TableModelDoc.java......................................................................................................99
A.7 Metadado.java..............................................................................................................100

LISTA DE ABREVIATURAS E SIGLAS

ACID

Atomicidade, Consistncia, Isolamento e Durabilidade

AGPL

Affero General Public License

API

Application Programming Interface

ASF

Apache Software Foundation

BASE

Basically Available, Soft state, Eventual consistency

BSON

Binary JSON

CQL

Cypher Query Language

HDFS

Hadoop Distributed Filesystem

HTTP

Hypertext Markup Language

JDK

Java Development Kit

JSON

JavaScript Object Notation

NOSQL

Not Only Structured Query Language

REST

Representational State Transfer

SGBD

Sistema de Gerenciamento de Banco de Dados

SGBDR

Sistema Gerenciador de Banco de Dados Relacional

SQL

Structured Query Language

SUMRIO
1 INTRODUO....................................................................................................................13
1.1 JUSTIFICATIVA..........................................................................................................14
1.2 OBJETIVOS..................................................................................................................14
1.3 METODOLOGIA.........................................................................................................15
1.4 ORGANIZAO DO TEXTO....................................................................................15
2 REVISO DE LITERATURA............................................................................................16
2.1 NOSQL..........................................................................................................................16
2.1.1 Chave/Valor............................................................................................................17
2.1.2 Orientado a colunas................................................................................................17
2.1.3 Orientado a documentos.........................................................................................18
2.1.4 Baseado em Grafos.................................................................................................19
2.2 SGBDs NOSQL............................................................................................................19
2.2.1 Redis.......................................................................................................................19
2.2.2 Riak.........................................................................................................................23
2.2.3 Cassandra................................................................................................................25
2.2.4 HBase......................................................................................................................30
2.2.5 CouchDB................................................................................................................32
2.2.6 MongoDB...............................................................................................................35
2.2.7 Neo4j......................................................................................................................39
2.3 COMPARATIVO ENTRE OS BANCOS DE DADOS NOSQL................................41
3 PROPOSTA DO TRABALHO............................................................................................44
3.1 PROPOSTA DE DESENVOLVIMENTO...................................................................44
3.2 DIAGRAMA DE CASOS DE USO.............................................................................46
3.2.1 Especificao do caso de uso Consultar banco de dados.......................................47
3.2.2 Especificao do caso de uso Visualizar metadados do documento.......................47
3.2.3 Especificao do caso de uso Inserir documento...................................................48
3.2.4 Especificao do caso de uso Alterar documento...................................................48
3.2.5 Especificao do caso de uso Remover documento...............................................48
4 DESENVOLVIMENTO DA APLICAO.......................................................................49
4.1 CLASSES IMPLEMENTADAS..................................................................................49
4.1.1 Classe BuscaDocumento e Classe BuscaDocAdm.................................................51
4.1.2 Classe NovoDocumento.........................................................................................53
4.1.3 Classe EditarDocumento........................................................................................54
4.1.4 Classe VisualizarDetalhes.......................................................................................54
4.1.5 Classe TableModelDoc e Classe Metadado............................................................54
4.2 UTILIZAO DA APLICAO...............................................................................55
4.2.1 Utilizao como Usurio Cliente............................................................................55
4.2.2 Utilizao como usurio Administrador.................................................................58
4.2.3 Tratamento de erros................................................................................................66
4.3 TESTES DE DESEMPENHO......................................................................................67
4.4 DOWNLOAD DA APLICAO.................................................................................68
5 CONCLUSES E TRABALHOS FUTUROS..................................................................69
REFERNCIAS......................................................................................................................71
APNDICES............................................................................................................................74

13

1 INTRODUO

Durante um longo perodo o modelo de dados relacional tem sido amplamente


utilizado pela maioria dos Sistemas de Gerenciamento de Banco de Dados (SGBD). Ainda
hoje assim. Entretanto, nos ltimos anos vem ocorrendo um crescimento significativo de
aplicaes, recursos web e tudo que se refere a sistemas computacionais. Essas aplicaes
geram grande volume de dados e tm o desafio de servir uma grande quantidade de
usurios, que esperam o perfeito funcionamento dos sistemas. Nesse cenrio, a utilizao do
modelo relacional no se mostra to eficiente, uma vez que este modelo possui srias
limitaes quanto escalabilidade horizontal, j que no foi projetado inicialmente para tal.
Como organizar os dados de um Sistema de Gerenciamento de Banco de Dados Relacional
(SGBDR) em sistemas distribudos complexo, quase sempre se acaba recorrendo
escalabilidade vertical para aumento de desempenho, ou seja, faz-se upgrade dos sistemas
de hardware do servidor. No entanto, a escalabilidade vertical tem limite. Para suprir as
deficincias encontradas nos SGBDRs e, principalmente, pela necessidade de escalabilidade
em bancos de dados, sem perda de desempenho, surgem alternativas ao modelo relacional.
Uma delas, a que ganhou mais destaque, o paradigma NoSQL (Orend, 2010).
O termo NoSQL foi utilizado pela primeira vez em 1998, por Carlo Strozzi, para
nomear um SGBD de cdigo aberto desenvolvido por ele e que no oferecia uma interface
Structured Query Language (SQL), entretanto, ainda era baseado na arquitetura relacional.
Era um sistema experimental e que no foi muito utilizado. O termo acabou caindo no
esquecimento at o ano de 2009, quando ressurgiu em um evento promovido por Johan
Oskarsson e Eric Evans. O evento teve como objetivo discutir o crescente surgimento de

14
solues open source de armazenamento de dados distribudos no relacionais. A partir de
ento o termo NoSQL foi redefinido para descrever as solues de armazenamento de dados
no relacionais, inclusive aquelas j existentes, como o caso do BigTable do Google,
lanado em 2004, e o Dynamo da Amazon, de 2007, ambas proprietrias. Aps isso, outros
projetos surgiram, como o Cassandra, o CouchDB, o MongoDB, etc.
Todas solues apresentam caractersticas em comum e outras particulares. A fim de
analisar as caractersticas dos bancos de dados NoSQL, ser realizado um estudo em alguns
bancos existentes e tambm ser desenvolvida uma aplicao para um desses bancos .

1.1 JUSTIFICATIVA
Tem-se comentado muito sobre as vantagens de utilizao de banco de dados NoSQL
como alternativa aos bancos relacionais, principalmente em cenrios onde faz-se necessrio
o armazenamento de grande volume de dados com alta disponibilidade e grande
escalabilidade. Muitas empresas (Google, Facebook, Amazon, LinkedIn, Twitter, etc...) tm
relatado sucesso no uso de banco de dados NoSQL, solucionando assim o problema de
escalabilidade e desempenho.
No entanto, preciso entender o contexto e dispor de uma anlise prvia sobre tais
bancos, de modo a escolher o que oferece as melhores funcionalidades e seja o mais
apropriado para determinada aplicao.
Sendo assim, sero selecionados alguns bancos de dados NoSQL, Open Source, para
a realizao de um estudo e comparao entre eles. A seleo dos bancos privilegia os que
estejam sendo mais utilizados no mercado, de modo a escolher um deles para o
desenvolvimento de uma aplicao.
1.2 OBJETIVOS
O objetivo do trabalho realizar uma pesquisa selecionando alguns Bancos de Dados
NoSQL para estudo e comparao, selecionando um dos bancos estudados para o
desenvolvimento de uma aplicao para manipular dados armazenados neste banco.

15
1.3 METODOLOGIA
A metodologia utilizada para atingir o objetivo do trabalho a que segue:

Pesquisa e seleo de NoSQL Databases;

Estudo individual de cada banco de dados;

Comparao dos Bancos de Dados e escolha de um para o desenvolvimento da


aplicao;

Definio da aplicao a ser desenvolvida;

Desenvolvimento da aplicao;

Testes da aplicao;

Elaborao da parte escrita.

1.4 ORGANIZAO DO TEXTO


O texto encontra-se estruturado da seguinte forma:
No captulo 2 so abordados os conceitos dos NoSQL Databases, as suas
caractersticas e subdivises. Alm disso, so apresentados os bancos de dados NoSQL
estudados neste trabalho e uma anlise comparativa entre eles.
O captulo 3 apresenta o Banco de Dados escolhido para realizar a implementao de
uma aplicao, explicando quais motivos levaram escolha deste. Tambm exposta a
proposta de aplicao desenvolvida, mostrando quais so as funcionalidades contidas na
ferramenta. Um diagrama de casos de uso usado para auxiliar o entendimento.
O captulo 4 mostra como foi desenvolvida a aplicao proposta, com uma breve
explicao sobre a aplicao. Tambm so comentadas quais as tecnologias utilizadas para o
desenvolvimento e, ainda, so exibidas algumas imagens da ferramenta para auxiliar na
explicao da utilizao da aplicao.
O captulo 5 apresenta o encerramento do trabalho, consideraes e sugestes de
melhorias para trabalhos futuros.

16

2 REVISO DE LITERATURA
Este captulo tem por finalidade apresentar os conceitos de algumas tecnologias
emergentes na Computao, como o caso dos Bancos de Dados NoSQL e o paradigma
BASE (Basically Available, Soft state, Eventual consistency) e, tambm, apresentar os
Bancos de Dados NoSQL selecionados para anlise neste trabalho.

2.1 NOSQL
Termo que descreve uma nova classe de banco de dados que vm tendo um
crescimento de uso acentuado nos ltimos anos, principalmente em funo de algumas
limitaes existentes nos bancos de dados relacionais. Apesar de o termo significar Not Only
SQL (no apenas SQL), a principal caracterstica desses bancos de no ter comportamento
relacional. Inclusive, no h nada que impea o uso de linguagem SQL. A implicao do
termo NoSQL que os objetivos desses bancos de dados, modernos e distribudos, so, na
maioria das vezes, distintos dos objetivos dos bancos de dados relacionais.
Os bancos de dados NoSQL geralmente seguem os princpios do paradigma BASE,
em detrimento das propriedades ACID, priorizando o desempenho e a disponibilidade. Esse
paradigma fornece aos bancos de dados caractersticas como: a) Basicamente disponvel
(Basically Available), ou seja, o sistema parece estar funcionando o tempo todo; b) Estado
leve (Soft State), ou seja, o sistema no precisa ser consistente o tempo todo; c)
Consistncia eventual (Eventual consistency), ou seja, o sistema torna-se consistente no
momento devido (Pritchett, 2008).
Com NoSQL Databases, pode-se gerenciar grande quantidade de dados sem perda
de desempenho. Isso plausvel porque esses bancos prezam pela inexistncia de transaes
e clusulas join. Ainda possuem configurao facilitada para escalabilidade horizontal e, na

17
maioria das vezes, suporte nativo replicao dos dados. A escalabilidade horizontal
corresponde adio de nodos (mquinas servidoras), enquanto a escalabilidade vertical o
aumento de desempenho de apenas um servidor central. A escalabilidade vertical pode ter
um limite de hardware, j na horizontal no h limites de nodos, porm mais complicada
de ser arquitetada e necessita de facilitadores. No caso, o uso de bancos de dados NoSQL
um facilitador.
Outra caracterstica dos NoSQL Databases o armazenamento de dados sem
estrutura pr-definida, ou seja, no preciso definir no momento de criao do banco os
tipos de dados que sero armazenados; isso feito dinamicamente, medida que so
inseridos.
Os bancos de dados NoSQL so classificados de acordo com a forma de armazenar
os dados. Existem 4 tipos de categorias: chave/valor, orientado a colunas, orientado a
documentos e baseados em grafos (Popescu, 2010).

2.1.1 Chave/Valor
O armazenamento do tipo chave/valor semelhante ao uso de mapas ou de
dicionrios, onde os dados so endereados por uma nica chave, permitindo aos clientes
colocar e solicitar valores por chaves. Esses sistemas podem conter dados estruturados ou
no estruturados. So teis para operaes simples, que so baseadas somente em atributos
chave. Por exemplo, sistemas com rpida troca de dados e com frequente escrita. Como a
maioria dos armazenamentos chave/valor mantm seu conjunto de dados em memria, eles
so bastante usados para cache de consultas SQL (Leavitt, 2010). Alguns bancos desta
categoria so: Redis, Riak, Voldemort, MemcacheDB, etc. (FindTheBest, 2012).

2.1.2 Orientado a colunas


Um SGBD orientado a colunas armazena seu contedo de forma inversa aos bancos de
dados orientados a linhas. Este formato de armazenar as informaes torna-se vantajoso para
Data Warehouses, onde agregaes so processadas sobre uma quantidade de dados de
caractersticas similares. Nesta categoria esto includos bancos, tais como Cassandra e Hbase
(FindTheBest, 2012).

18
2.1.3 Orientado a documentos
Um banco de dados orientado a documentos armazena, recupera e gerencia dados
semiestruturados. O elemento dos dados chamado documento. Os documentos so
endereados no banco de dados via uma chave nica que representa o documento. Uma das
caractersticas de um banco de dados orientado a documentos que, alm da simples
chave/valor de pesquisa, possvel recuperar um documento atravs de uma API, ou
linguagem de consulta disponibilizada pelo banco. Todos os banco de dados correntes
fornecem suporte a documentos no formato JSON (Leavitt, 2010).
O JSON um padro aberto de estruturao de dados baseado em texto e legvel por
humanos, utilizado para a serializao de dados. Foi projetado com o objetivo de ser
simples, porttil, textual, e um subconjunto do JavaScript e tem se mostrado uma tima
alternativa ao XML, inclusive sendo nativo de armazenamento em alguns bancos de dados
(JSON, 2012).
Um exemplo de documento JSON pode ser visto na Figura 2.1.

Figura 2.1: Exemplo documento JSON (Wikipedia, 2012)

Outro formato de documento utilizado o BSON, semelhante ao JSON, porm com


armazenado em binrio, consistindo em uma lista de elementos chave/valor, onde a chave
uma string e o valor pode ser string, inteiro, data, booleano, nulo, objeto BSON ou matriz
BSON (BSON, 2012).
Nessa categoria esto includos bancos, tais como: MongoDB, CouchDB,

19
Couchbase, RavenDB, SimpleDB, etc. (FindTheBest, 2012).

2.1.4 Baseado em Grafos


O armazenamento baseado em grafos fundamenta-se na teoria dos grafos. Em geral,
vemos que grafo consiste de ns, propriedades e arestas. Os ns representam as entidades,
as propriedades representam os atributos e as arestas representam as relaes (Leavitt,
2010). Como exemplos de bancos de dados desta categoria podemos citar o InfoGrid e
Neo4j (FindTheBest, 2012).

2.2 SGBDs NOSQL


Nesta seo encontra-se o estudo dos Bancos de Dados NoSQL pesquisados para a
realizao deste trabalho. Os bancos escolhidos para anlise foram aqueles que
frequentemente so citados como exemplos nas pesquisas anteriores.

2.2.1 Redis
O REmote DIctionary Service (Redis) um banco de dados de cdigo aberto do tipo
chave/valor semi-persistente. Atualmente est na verso 2.6.2. Seu cdigo escrito em
linguagem C sob a licena BSD e funciona na maioria dos sistemas POSIX, como linux,
BSD, Mac OS e Solaris.
O Redis est presente em diversos servios, entre eles o gitHub, o StackOverflow,
alm de outros. Seu melhor uso em sistemas que exigem rpida troca de dados e muita
frequncia de escrita, como por exemplo, em aplicaes com dados em tempo real, preo
das aes, etc. (Seguin, 2012).
Esse banco de dados referido, inclusive pelo seu autor, como um servidor de
estrutura de dados, onde suas chaves podem conter strings, hashes, listas, conjuntos e
conjuntos ordenados.
Sendo o Redis um banco de dados com armazenamento em memria, o seu ponto
forte a velocidade de leitura e gravao, podendo chegar a mais de 100.000 operaes por
segundo (Redmond, 2012).

20

2.2.1.1 Arquitetura
O Redis um banco de dados do tipo cliente/servidor. Ele possui um servidor que
recebe conexes, por padro na porta 6379, e um cliente que se envia comandos atravs de
um protocolo de comunicao. A Figura 2.2 mostra o diagrama da arquitetura.

Figura 2.2: Arquitetura Redis (Campanelli, 2011).

O Redis possui um servidor executando um servio, o redis-server, que conversa


com os clientes atravs de um protocolo redis. Esse protocolo deve criar uma conexo TCP
possibilitando que os clientes enviem comandos ao servidor.
O cliente oficial do redis o redis-cli, desenvolvido em C e executado por linha de
comando, mas tm sido desenvolvidos outros projetos em diferentes linguagens como C++,
Haskell, Java, Objective-C, Perl, PHP, Ruby, Python, etc. No site oficial do Redis h uma
relao dos projetos de clientes (Redis, 2010).
Os clientes possuem uma srie de grupos de comandos que podem ser executados.
Esses comandos so enviados ao servidor, que recebe, processa e envia ao cliente uma

21
resposta. Assim como outros bancos NoSQL, o Redis completamente comprometido com
velocidade, faz pouco uso de recursos, de segurana e opes de configuraes triviais para
ganhos de escalabilidade.
Nota-se tambm que possvel implementar uma arquitetura master/slave no Redis
Server para ganho de desempenho, sendo possvel replicao dos dados, armazenados em
memria RAM, para outros servidores, caso faz-se necessrio. Vale ressaltar que o
importante a quantidade de memria RAM disponvel para o banco de dados, pois todos
os dados so armazenados em memria, inclusive em uma replicao de servidores
(Redmond, 2012).
Outra tcnica que pode ser utilizada a persistncia dos dados da memria do
servidor master em disco de um servidor slave, evitando uma latncia maior no
processamento do servidor principal.

2.2.1.2 Armazenamento
No que diz respeito ao armazenamento, pode-se dizer que o Redis semipersistente,
isso porque os dados so obrigatoriamente mantidos na memria RAM. Isso um fator
limitante para a quantidade de dados armazenados (Ippolito, 2009). Entretanto, tambm
possvel persistir os dados em disco. Esse procedimento torna-se importante para uma
possvel recuperao, medida que Redis no oferece tolerncia a falhas e os dados
mantidos em memria sero perdidos em caso de falha no servidor (Strauch, 2011).
O Redis um banco de dados do tipo chave/valor, sendo possvel trabalhar com
strings, colees de listas, de conjuntos, conjuntos ordenados e hashes. No entanto, tudo
representado e armazenado na memria como string (Tiwari, 2011). De maneira atmica,
pode-se fazer operao de unio, interseco e diferenas entre conjuntos, alm de trabalhar
com listas, adicionando e removendo elementos de forma organizada.
Para o armazenamento em disco, h duas formas de persistir os dados. Uma delas ,
de tempos em tempos, gravar uma cpia do contedo da memria RAM em disco. Esse
armazenamento conhecido como persistncia RDB. A outra a persistncia AOF (Append
Only File), onde cada comando enviado ao servidor anexado em um arquivo de log
(Redis, 2012).
Na persistncia RDB so criados snapshots do conjunto de dados que esto na
memria, que sero guardados em disco em um arquivo. Esse procedimento pode ser

22
realizado periodicamente caso um nmero mnimo de alteraes tenham sido realizadas.
Como alternativa, pode ser chamado manualmente atravs dos comandos SAVE ou
BGSAVE do Redis. J na persistncia AOF todos os comandos recebidos pelo servidor so
guardados em arquivo de log. Este arquivo pode ser usado para recuperao em caso de
falha, reconstruindo o conjunto de dados original (Redmond, 2012).
Como foi comentado anteriormente, possvel utilizar vrios servidores para
armazenamento dos dados em memria. Tambm possvel utilizar servidores slaves para
efetuar persistncia dos dados, evitando a perda de desempenho com I/O no servidor
principal.

2.2.1.3 Download e instalao


A seguir ser descrito como efetuar o download do banco de dados Redis e o
procedimento para sua execuo. A instalao ser efetuada no sistema operacional linux,
utilizando a distribuio Ubuntu 10.04.
Em um terminal, digite os seguintes comandos:
$ wget http://redis.googlecode.com/files/redis-2.4.6.tar.gz
$ tar xzf redis-2.4.6.tar.gz
$ cd redis-2.4.6
$ make
Para iniciar o servidor:
$ src/redis-server
O cliente oficial pode ser inicializado da seguinte forma:
$ src/redis-cli
O Redis possui muitos comandos que podem ser executados, para criar listas,
colees, conjuntos. A seguir podemos test-lo com o cliente:
redis> set nome Joo
OK
redis> get nome
"Joo"

23
2.2.2 Riak
Riak um banco de dados do tipo chave/valor, distribudo e escalvel. Ele foi
desenvolvido pela empresa Basho Technlogies, encontra-se atualmente na verso 1.2.0. Ele
escrito na linguagem Erlang e est sob a licena Apache 2.0. Ele possui pacote para
instalao nos sistemas operacionais Linux, Mac OS e Solaris. (Riak, 2012)

2.2.2.1 Arquitetura
um banco de dados totalmente distribudo. Ele pode ser acessado atravs do
protocolo HTTP/REST ou de uma interface Erlang nativa. No caso de uma aplicao
desenvolvida em Erlang, o acesso com a interface nativa pode ser simplificado, nos outros
casos convm utilizar a API HTTP/REST, j que a maioria das linguagens tem embutidas
primitivas para requisitar recursos sobre HTTP. H tambm uma srie de bibliotecas para
clientes em vrias linguagens de programao, como Java, Python e Ruby. Todos os clientes
oferecem suporte para os mtodos habituais de HTTP: PUT, GET, POST e DELETE.

Figura 2.3: Modelo de Cluster no Riak (Riak, 2012).

O conceito de cluster o ponto central no banco de dados Riak, sendo que no existe
o conceito de n master, ou seja, todos os ns so iguais, o que d uma maior resistncia a
falhas, desde que exista a replicao dos dados. Cada cluster um espao inteiro de 160 bits

24
de hashes binrios de pares bucket/chave, divididos em parties iguais. Os servidores
fsicos, referidos no cluster como ns, executam certo nmero de ns virtuais, os chamados
vnodes. Cada vnode requisita uma partio deste anel e responsvel por armazenar
uma poro separada do espao das chaves. O nmero de vnodes por n calculado por
numero de parties/nmero de ns.
Na Figura 2.3 pode-se ter uma noo de como o cluster, supondo um anel com 32
parties em 4 ns fsicos, cada n fsico ser responsvel por 8 vnodes.
Os ns podem ser adicionados ou removidos do cluster de forma dinmica, sem
reiniciar o servio, e o Riak se encarregar da distribuio dos dados. A replicao faz parte
nativamente do Riak (Riak, 2012).

2.2.2.2 Armazenamento
Quanto ao armazenamento, Riak composto por trs conceitos: buckets, chaves e
valores. Buckets so semelhantes colees, ou a tabelas, e agrupam objetos relacionados
ou semelhantes. Os buckets possuem algumas propriedades que definem como os objetos
so armazenados nele, como, por exemplo, a varivel n_val que define quantas vezes um
objeto ser replicado no cluster, sendo til para o caso de falha em um n.
Buckets e chaves so as nicas maneiras de organizar os dados no Riak. Os dados
so armazenados e referenciados pelo par bucket/chave. Cada chave est ligada a um nico
valor que pode ser de qualquer tipo, desde texto plano, arquivos binrios, html ou at
mesmo documentos no estilo JSON, inclusive, sendo referenciado por alguns como uma
espcie de armazenamento do tipo orientado a documentos (Riak, 2012).

2.2.2.3 Download e instalao


Possui pacotes para instalao em sistema linux, Mac OS e Solaris. Para instalar o
Riak, basta acessar o site http://basho.com/resources/downloads/ e efetuar o download do
pacote especfico. No caso, a instalao foi realizada no Ubuntu 10.04.
Depois de efetuado o download, basta indicar o comando de instalao:
$ dpkg -i riak_1.2.0-1_i386.deb

25
Aps isso pode-se inserir algum elemento de teste, onde a insero efetuada
baseada no modelo: http://SERVER:PORT/riak/BUCKET/KEY
$ curl -v -X PUT http://localhost:8098/riak/favs/db \
-H "Content-Type: text/html" \
-d "<html><body><h1>My new favorite DB is RIAK</h1></body></html>"
Assim, foi armazenado no bucket favs, com chave db e o valor, que no caso foi
o contedo de um documento html.
Na sequncia vamos incluir um documento estilo JSON com o seguinte contedo:
{"nickname" : "The Wonder Dog", "breed" : "German Shepherd"}
$ curl -v -X PUT http://localhost:8098/riak/animals/ace \
-H "Content-Type: application/json" \
-d '{"nickname" : "The Wonder Dog", "breed" : "German Shepherd"}'
No site do Riak http://docs.basho.com/riak/latest/ possvel encontrar alguma
documentao sobre a utilizao do Riak.

2.2.3 Cassandra
Cassandra um banco de dados de armazenamento de dados distribudo, orientado a
colunas. Escrito em Java, foi desenvolvido inicialmente pelo Facebook e, atualmente, est
na verso 1.1.5. mantido por desenvolvedores da Apache e colaboradores. Est sob a
licena Apache 2.0.

2.2.3.1 Arquitetura
O Banco de Dados Cassandra foi projetado para ser distribudo ao longo de vrias
mquinas que operam em conjunto, como uma nica instncia ao usurio final. De maneira
simplificada, pode-se dizer que Cassandra composto por um cluster, ns, keyspaces e
famlia de colunas.

26
A estrutura mais externa o cluster, tambm chamado de anel, como pode ser visto
na Figura 2.4, isso porque Cassandra atribui dados aos ns do cluster organizando-os em
forma de anel. Um cluster um continer para keyspaces.

Figura 2.4: Cluster do Cassandra (Cassandra, 2012)

Os dados so distribudos de forma transparente, qualquer n aceita qualquer


solicitao (leitura, gravao ou excluso) e encaminha ao n correto, sendo que no existe
distino, todos os ns so logicamente iguais. possvel ter um cluster com muitos ns,
que capaz de lidar com uma quantidade enorme de dados, na casa dos petabytes, por
exemplo.

2.2.3.2 Armazenamento
O Keyspace o recipiente para os dados do aplicativo, semelhante a um banco de
dados no modelo relacional. Da mesma forma que um banco de dados um continer para
tabelas, um keyspace um continer para uma lista de uma ou mais famlias de colunas.

27
Keyspace possui nome e conjunto de atributos que definem o seu comportamento.
possvel configurar alguns atributos bsicos como, por exemplo, o Replication Factor que
define o nmero de ns que agiro como cpias de cada registro inserido. importante
ressaltar que a cada quanto maior este nmero, menor o desempenho. Outra observao fazse quanto ao nmero de keyspaces por aplicao, nada impede que sejam criadas mltiplas
keyspaces, entretanto, recomenda-se o uso de apenas uma por aplicao (HEWITT, 2010).
Se o keyspace um continer para famlia de colunas, uma famlia de coluna
continer para uma coleo ordenada de linhas, cada uma das quais uma coleo ordenada
de colunas.
Apache Cassandra considerado livre de esquema, ou seja, as colunas no
necessariamente precisam conter os mesmos campos, sendo possvel adicionar livremente
qualquer coluna, de acordo com a necessidade, para qualquer famlia de coluna.

Figura 2.5: Modelo de dados do Apache Cassandra ( Cho, 2010)

Na Figura 2.5 podem ser visualizados todos os objetos mencionados acima. H um


keyspace, duas famlias de colunas contendo linhas que no seguem um esquema fixo.
Os dados so escritos em estruturas de memria (memtables) e, em seguida, escritas
em disco, uma vez que a estrutura de memria estiver cheia. Memtable possui tamanho
padro de 128MB. H algumas questes a ressaltar, todos os dados de uma linha devem

28
caber em uma nica mquina do cluster, para que esse seja replicado. O tamanho mximo
de uma coluna no pode ultrapassar 2GB e o podem existir no mximo 2 bilhes de colunas
por linha.
Como mencionado anteriormente, Apache Cassandra um tima servidor para
grandes quantidades de dados, com fcil processo de gravao.

2.2.3.3 Download e instalao


Antes de instalar o Cassandra, preciso verificar a existncia do Java instalado na
mquina servidora.
Para a instalao, recomenda-se adicionar o endereo dos repositrios ao arquivo de
configurao do Ubuntu /etc/apt/sources.list, como mostra a Figura 2.6.

Figura 2.6: Repositrio do Apache Cassandra

Aps isso, pode-se fazer o download da chave pblica do repositrio, seguindo o


exemplo da Figura 2.7:

Figura 2.7: Chave Pblica do repositrio

Na Figura 2.8, podem ser vistos os comandos para a instalao do Cassandra no


Ubuntu 10.04:

Figura 2.8: Instalao do Apache Cassandra

O Cassandra possui um cliente padro para console, que pode ser iniciado pelo
terminal atravs do comando:
$ cassandra-cli -host localhost -port 9160
Para testar, pode-se faz-lo informando alguns comandos bsicos de insero, busca,
etc. Para isto, cria-se um novo keyspace chamado teste, por exemplo:

29
$ create keyspace teste;
A seguir, criar uma nova famlia de colunas, com o nome User:
$ create column family Usuario with comparator = UTF8Type;
AND column_metadata = [
{ column_name: primeiro, validation_class: UTF8Type},
{ column_name: ultimo, validation_class: UTF8Type},
{ column_name: idade, validation_class: UTF8Type, index_type: KEYS}
];
Neste exemplo, as colunas so estticas, porque foram definidas anteriormente. P ara
adicionar um elemento, pode-se fazer da seguinte forma:
$ set Usuario['jsilva']['primeiro'] = 'Joao';
$ set Usuario['jsilva']['ultimo'] = 'Silva';
$ set Usuario['jsilva']['idade'] = '56';
A seguir um exemplo de como criar uma famlia de colunas dinmicas:
$ create column family Usuario
WITH comparator = TimeUUIDType
AND key_validation_class=UTF8Type
AND default_validation_class = UTF8Type;
Para consultar algum registro, retornando, por exemplo, o registro anteriormente
inserido, pode-se realizar da seguinte forma:
$ get Usuario where idade = '56';
Existe tambm uma ferramenta grfica para administrar os clusters no Apache
Cassandra, semelhante ao phpMyAdmin, o Cassandra Cluster Admin. Com ele possvel
criar, editar, excluir keyspaces, famlias de colunas, exibir, procurar dados e inserir linhas.
Entretanto, a ferramenta no foi testada.
Alm do cliente padro, existem clientes para Java, PHP, C++, Perl, entre outros. H
tambm suporte linguagem de consulta CQL, semelhante SQL, tendo drivers
disponveis para Java e Python.

30
2.2.4 HBase
Hbase um banco de dados orientado a colunas, altamente escalvel e distribudo,
que suporta armazenamento de dados estruturados para grandes tabelas. Foi desenvolvido, e
mantido pela Apache Software Foundation (ASF). escrito na linguagem Java, sob a
licena Apache 2.0. Est atualmente na verso 0.94. Sua utilizao recomendvel quando
necessrio acesso de leitura/escrita em tempo real e aleatrio para grandes dados (HBase,
2012).

2.2.4.1 Arquitetura
O Hbase um subprojeto do Apache Hadoop, que desenvolve softwares open source
para computao distribuda e escalvel. De outro subprojeto do Apache Hadoop vm o
HDFS, sistema de arquivos que oferece acesso com alta taxa de transferncia para os dados
da aplicao. O Hbase pode ser executado tanto em sistemas de arquivos comuns, como no
sistema de arquivos HDFS, que tambm desenvolvido pela Apache e oferece acesso com
alta taxa de transferncia para os dados da aplicao. Entretanto, com o HDFS possvel ter
uma gama maior de recursos para o Hbase, isto porque so sistemas desenvolvidos em
paralelo e pela mesma empresa.
Existem 3 modos de executar o servidor Hbase:
- Stand-alone, onde uma mquina trabalha sozinha;
- Pseudodistributed, onde um n fingindo ser um cluster;
- Fully distributed o modo onde h vrios ns trabalhando em conjunto.
Na Figura 2.9 possvel visualizar a arquitetura do HBase.

31

Figura 2.9: Arquitetura HBase.

Para executar a forma totalmente distribuda preciso ter um cluster ZooKeeper


rodando. ZooKeeper um servio de Coordenao para aplicaes distribudas. Ainda
necessrio ter um servidor master e vrios servidores regionais como mostrado na Figura
2.X

2.2.4.2 Armazenamento
O HBase suporta dados no estruturados e parcialmente estruturados. Para fazer isso,
os dados so organizados em famlias de colunas. endereado um registro individual,
chamado de clula no Hbase, com uma combinao de row, column e timestamp. No
necessrio definir a tabela com antecedncia, pode-se simplesmente nomear uma famlia de
colunas e ento permitir que a clula se qualifique para ser determinada em tempo de
execuo. Isso permite que voc seja bastante flexvel e suporta uma abordagem gil de
desenvolvimento.

32
2.2.4.3 Download e instalao
O Hbase est disponvel oficialmente para Linux e o download pode ser realizado no
endereo http://www.apache.org/dyn/closer.cgi/hbase/. Entretanto, no foi obtido sucesso na
instalao do software no Ubuntu 10.04, mesmo que tenha suporte para este sistema
operacional. Eram exigidas muitas configuraes adicionais, importaes de bibliotecas e
instalao do Java. Mesmo realizando o procedimento indicado na documentao, no se
obteve xito.

2.2.5 CouchDB
Apache CouchDB um banco de dados escalvel, tolerante a falhas e orientado a
documentos de esquema livre. Foi desenvolvido por Damien Kat, ex-desenvolvedor da
IBM, em 2005. Posteriormente, em 2008, foi repassado Apache, que deu continuidade ao
projeto. escrito na linguagem Erlang e est sob a licena Apache 2.0. Est na verso 1.2 e
possui pacote de instalao para Linux, Mac Os e, recentemente, tambm para Windows
(CouchDB, 2012).

2.2.5.1 Arquitetura
O CouchDB utiliza uma API HTTP/REST para a manipulao dos dados, portanto a
comunicao entre entre cliente e servidor pode ser realizada em qualquer aplicao que
possa comunicar-se por HTTP. As operaes bsicas de um banco de dados so mapeadas
para as operaes do protocolo HTTP, como GET, PUT, POST, DELETE, para ler,
armazenar, substituir e remover objetos armazenados.
Alm da API REST/HTTP que prov acesso a qualquer aplicao com suporte ao
protocolo HTTP, o CouchDB oferece um servidor web, chamado Futon, que pode ser
acessado pelo browser atravs do endereo http://localhost:5984/_utils/, onde possvel
gerenciar os bancos e documentos individualmente.
Na Figura 2.X tem-se um modelo de arquitetura do CouchDB, indicando que a
requisio que feita atravs do cliente HTTP, chegando ao mdulo do CouchDB que trata
das requisies. Tem-se tambm os processos que esto rodando no servidor e so

33
responsveis pelas tarefas de replicao, visualizao e armazenamento dos dados.

Figura 2.10: Arquitetura CouchDB.

A arquitetura do CouchDB consiste em um servidor de banco de dados master que


possui um ou mais bancos de dados criados. Os bancos so compostos por objetos, que so
documentos do tipo JSON, de esquema livre, ou seja, em uma mesma base de dados os
documento no precisam ter os mesmos campos. Entretanto, recomenda-se armazenar
documentos semelhantes em um mesmo banco de dados.
CouchDB suporta mltiplas rplicas do banco de dados rodando em diferentes
servidores e fornece um mecanismo para sincronizao destes dados. H um processo,
replicador, executando que possibilita informar a origem e o destino do servidor, realizada
uma verificao pela data e caso houve mudanas, a cpia sobrescrito no servidor slave.
As replicaes so realizadas de forma assncrona, de forma que no compromete a
velocidade de escrita e leitura (ANDERSON, 2010).

2.2.5.2 Armazenamento
Os documentos so a unidade primria de dados no CouchDB e so constitudos de
campos de pares chave ou nome e valor. Os nomes das chaves devem ser nicos dentro de
um documento e o valor atribudo pode ser uma string, nmero, booleano, data, listas,
entretanto, no podem existir documentos aninhados. Existem dois campos fixos em
qualquer documento, que servem para identificao nica, um ID do documento e um
nmero de reviso, onde o ID nico para qualquer novo documento e o campo revisor

34
serve para identificar as vrias modificaes realizadas em um documento (Strauch, 2011).
Um ponto importante sobre o armazenamento que a edio de um documento na
verdade a criao uma nova verso do documento, com o mesmo identificador ID , com as
alteraes efetuadas e um novo nmero de reviso. Isto pode ser til muitas vezes, como
para recuperao de dados em caso de falha, mas tambm desperdiado muito espao em
disco com arquivos antigos e at certo ponto inteis. As modificaes s podem ser
realizadas na ltima verso do documento. Tambm, no possvel excluir uma verso,
somente o documento por completo.
Para atualizaes de documentos utilizado o modelo lockless, onde o documento
carregado na aplicao cliente onde se realiza a edio, e guarda-se no banco de dados
novamente. Caso outro cliente editou o mesmo documento, ser recebido uma mensagem de
conflito de edio ao tentar salvar. Para resolver este problema, a verso mais recente do
documento poder ser aberta, isso acontece porque no oferecido mecanismo de bloqueio
na escrita. As atualizaes de documentos (insero, edio ou remoo) so atmicas, ou
seja, so totalmente salvos ou nada salvo, no existem salvamentos parciais.
Os documentos so armazenados utilizando um mecanismo de indexao sobre
estruturas de rvores B, que so excelentes estruturas para manter os dados classificados e
propiciam rapidez nas buscas, inseres e excluses de documentos (ANDERSON, 2010).

2.2.5.3 Download e instalao


possvel fazer o download atravs do site oficial http://couchdb.apache.org/. H
pacotes disponveis para Linux, e Mac OS e, desde 2010, tambm para Windows. No
Ubuntu 10.04, j est includo na central de softwares, ento pode ser instalado pelo
comando aptitude install couchdb.
Como o CouchDB tem uma API REST, a conexo entre cliente e servidor pode ser
realizada entre qualquer aplicao que possua suporte ao protocolo HTTP. Nos exemplos,
ser utilizado a ferramenta cURL.
Criando um novo banco de dados Usuario:
$ curl -X PUT http://127.0.0.1:5984/usuario
Inserindo um documento banco de dados:
$ curl -X PUT http://127.0.0.1:5984/usuario/6e1295ed6c29495e54cc05947f18c8af
\ -d '{Nome: Joao da Silva, Idade: 56}'

35

2.2.6 MongoDB
O MongoDB um banco de dados orientado a documentos, livre de esquema, escrito
em C++, sob a licena AGPL verso 3.0. Foi desenvolvido em um projeto open source,
impulsionado principalmente pela empresa 10gen, que tambm oferece servios
profissionais em torno MongoDB. Atualmente, continua sendo mantido pela mesma
empresa, est na verso 2.2.2 e em constante desenvolvimento. O seu nome, Mongo, deriva
do adjetivo humongous, monstruoso em portugus (MongoDB, 2012).
De acordo com seus desenvolvedores, o objetivo principal do MongoDB preencher
a lacuna entre os bancos de dados de armazenamento chave/valor, rpidos e altamente
escalveis, e os tradicionais sistemas de gerenciamento de banco de dados relacionais, que
possuem grande quantidade de recursos. Assim, MongoDB foi projetado para otimizao
de desempenho, facilidade de escalabilidade horizontal, alta disponibilidade e capacidade
de consultas avanadas (Strauch, 2011).

2.2.6.1 Arquitetura
O aplicativo MongoDB composto por dois tipos de servios, o processo servidor
mongod que o ncleo do banco de dados e o servio mongos para autosharding. Sharding
a diviso dos dados em vrios ns, sendo utilizado quando faz-se necessrio
balanceamento de carga . O processo servidor pode rodar tanto em arquiteturas 32 como 64bit, no entanto, recomendado o uso de 64-bit, uma vez que o tamanho mximo de um
banco de dados limitado 2GB no modo 32-bit. Alm dos servios do aplicativo servidor,
h tambm servio cliente mongo, que um cliente shell padro do MongoDB utilizado
para conectar-se ao servidor atravs da porta 27017. Entretanto, h uma grande variedade de
drivers oficiais disponveis, como C, C++, Haskell, Java, PHP, entre outros, todos eles
esto sob a licena Apache. Tambm possvel conectar atravs da interface HTTP/REST
na porta 28017, permitindo a manipulao de entradas via HTTP.
O servidor MongoDB pode hospedar mais de um banco de dados, independentes
entre si, armazenados separadamente. Um banco de dados contm um uma ou mais colees
constitudas por documentos BSON (Binary JSON), que so estruturados como documentos

36
JSON, com esquema dinmico, fazendo com que a integrao de dados em certos tipos de
aplicaes sejam mais fceis e rpidos (MongoDB, 2012).
As consultas so expressas em sintaxe como JSON e so enviadas ao servidor como
objetos BSON pelo driver do banco de dados. O modelo permite consultas a todos os
documentos dentro de uma coleo, incluindo objetos e matrizes incorporadas. MongoDB
no possui transaes, tampouco joins, ficando a cargo do desenvolvedor implement-las,
se necessrio, em uma aplicao. possvel inclusive relacionar documentos de colees
distintas.
Quanto aos recursos disponveis, vale ressaltar o suporte automtico para a
realizao de Sharding. O sistema de banco de dados pode ser distribudo atravs de um
cluster de mquinas. O cluster consiste em trs componentes, ns Shard, servidores de
configurao e servios de roteamento chamados mongos. Na Figura 2.9, mostrada a seguir,
possvel visualizar o cluster.

Figura 2.11: Arquitetura Cluster MongoDB (Orend, 2010).

Os ns Shard so responsveis por armazenar os dados atuais, podendo inclusive ser


replicados para redundncia em caso de falha. Os servidores de configurao so usados
para armazenar os metadados e rotear informao do cluster de MongoDB. Os Mongos so

37
responsveis por rotear os processos, otimizando o desempenho das tarefas requisitadas
pelos clientes (Orend, 2010).
Outro recurso importante o GridFS, que serve para armazenar e recuperar arquivos
que excedam o limite de 16M dos documentos BSON. Os arquivos so divididos em partes
e armazenados em uma coleo, em outra coleo so armazenados os metadados do
arquivo. til para armazenar arquivos grandes, como udio e vdeo (MongoDB, 2012).

2.2.6.2 Armazenamento
Quanto ao armazenamento, de forma simplificada pode-se dizer que o servidor
MongoDB contm um ou mais bancos de dados, independentes, armazenados
separadamente. Cada banco de dados composto por uma ou mais colees constitudas de
documentos estruturados BSON, estes, so armazenados como BSON objetos, que so
binrios codificados como objetos JSON. BSON suporta estrutura de objetos aninhados
com objetos e matrizes embutidos, assim como JSON. Cabe ressaltar que o tamanho
mximo de cada documento 16MB (Strauch, 2011).
Como j mencionado, os documentos no MongoDB so organizados em colees.
Cada coleo pode conter qualquer tipo de documento, entretanto aconselha-se utilizar uma
coleo para cada tipo de documento. Cada documento tem um campo de ID, que usado
como uma chave primria ObjectID. Estes ndices so armazenados em estruturas como
rvore B. Para permitir consultas rpidas, o desenvolvedor pode criar um ndice para cada
campo de consulta possvel um documento. MongoDB tambm suporta indexao sobre os
objetos embutidos e matrizes.
MongoDB usa arquivos de memria mapeada, que mapeia diretamente um arquivo
armazenado em disco para um array de bytes em memria virtual, no memria fsica
RAM, onde a lgica de acesso aos dados implementado usando aritmtica de ponteiro. O
uso de arquivos mapeados em memria eficiente para melhorar o desempenho ( Orend,
2010).

2.2.6.3 Download e instalao


Esto disponveis distribuies binrias para Windows, Mac OS X, Linux e Solaris.

38
Todo o processo de instalao e execuo descrito aqui foi realizado no Sistema
Operacional Linux, distro Ubuntu 10.04. Para outros sistemas operacionais, basta acessar o
site http://www.mongodb.org/downloads e efetuar o download para a distribuio
especfica.
Para

instalao

do

MongoDB

deve-se

adicionar

endereo

deb

http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen ao arquivo de


configurao onde esto listados os repositrios utilizados no Ubuntu, este arquivo
usualmente encontrado no diretrio /etc/apt/sources.list. Em um terminal digite o
comando aptitude install mongodb-10gen, isto instalar os pacotes necessrios ao
funcionamento do banco de dados.
No arquivo /etc/mongo.conf escontra-se as configuraes do servidor, que podem
ser alteradas de acordo com a necessidade, como porta, local de armazenamento dos dados,
etc. Por padro, os arquivos de dados so armazenados no diretrio /var/lib/mongodb e o
log em "/var/log/mongodb.
Para iniciar o servidor basta chamar o processo mongod atravs do terminal:
$ service mongodb start
O servio cliente pode ser inicializado atravs do comando:
$ mongo
Por padro, o shell do Mongo se conecta ao banco de dados test, utiliizando a
interface localhost como padro. Para conectar-se a diferentes bancos, servidor, etc.
necessrio especificar explicitamente. Com o cliente j conectado ao banco, pode-se
efetuar alguns testes, como insero, remoo, busca, etc.
Primeiramente vamos alterar para outro banco de dados, para isto use o comando:
> use testeDB;
Com isto passaremos a trabalhar com o banco de dados testeDB que, caso ainda
no exista, ser criado no momento de insero do primeiro documento. Outro detalhe que
no necessrio que a coleo exista no momento em que vamos inserir o documento, pois
ser criada quando da insero do primeiro documento. Agora podemos inserir um
documento para teste, o faremos no banco que testeDB que estamos trabalhando e na
coleo, ainda inexistente, testeColecao. Para isto, executamos o comando:
> db.testeColecao.save({nome: "Joao da Silva", idade: "56"});
As consultas no MongoDB so baseadas em documentos, ento podemos listas todos
os documentos na coleo testeColecao com o seguinte comando:
> db.testeColecao.find( );

39
Para listar somente os documentos que contenham a chave idade, com valor 56
procedemos da seguinte maneira:
> db.testeColecao.find( {idade: 56});
O MongoDB possui ainda uma srie de operadores para consultas avanadas como
por exemplo (o significado entre parnteses): $lt (menor que), $lte (menor ou igual que) $gt
(maior que), $gte (maior ou igual que), $ne (diferente de), entre outros. Na documentao
oficial possvel consult-los.

2.2.7 Neo4j
Neo4j um banco de dados de cdigo aberto, orientado a grafos. Foi desenvolvido
pela empresa Neo Technology, em 2007. escrito na linguagem Java e possui dois tipos de
licenas, uma de cdigo aberto, GPLv3 e outra, com os mdulos adicionais, comercial sob a
licena AGPLv3.
descrito por seus desenvolvedores como um banco de dados integrado, baseado em
disco, com mecanismo de persistncia em Java totalmente transacional que armazena dados
estruturados em grafos. Apresenta transaes ACID, alta disponibilidade (Neo4j, 2012).

2.2.7.1 Arquitetura e armazenamento


O Neo4j faz valer a conceito de orientao a grafos, permitindo que os dados sejam
persistidos, percorridos e visualizados da mesma maneira que os grafos.
Ao contrrio dos outros bancos de dados NoSQL, o Neo4j mantm algumas
caractersticas que se tornaram comuns em bancos de dados relacionais, como controle de
transaes e a propriedade ACID.
As unidades fundamentais que formam um grafo so os ns e relacionamentos. No
Neo4j, tanto ns como relacionamentos podem conter propriedades. As Relaes entre ns
so uma parte chave do banco de dados baseado em grafo, eles permitem encontrar dados
relacionados.
Assim como os ns, relacionamentos tambm podem ter propriedades e um
relacionamento que conecta dois ns, garante que o n inicial e final so vlidos.
interessante ressaltar que no Neo4j, os relacionamentos so sem esquema definido, ou seja,

40
podem ser de qualquer tipo.
As propriedades dos ns e relacionamentos so pares chave/valor, onde a chave
uma string e os valores podem ser tipos primitivos como string, int, booleano, ou matriz de
um tipo primitivo. O caminho um ou mais ns de de ligao com os relacionamentos
(Redmond, 2012).
O banco de dados Neo4j recomendvel para situaes em que seriam necessrias
muitas operaes, como pesquisas extremamente complexas nos bancos de dados
relacionais. Neo4j baseia-se na teoria dos grafos.
Quanto a disponibilidade, Neo4j foi projetado para ser facilmente replicado entre
servidor master e slave com uma simples mudana de configurao do servio
EmbeddedGraphDatabase

para

modo

de

alta

disponibilidade

HighlyAvailableGraphDatabase. Ao executar neste modo, h sempre um nico master e


zero ou mais slaves. No entanto, o servio de alta disponibilidade s est presente na edio
comercial.
O Neo4j possui uma linguagem prpria para consulta, a CQL, que permite uma
expressiva e eficiente consulta a armazenamento em grafo. A linguagem baseada em pattern
matching e tem sintaxe semelhante ao SQL (Neo4j, 2012).
Na Figura 2.10 tem-se um exemplo de um modelo de banco de dados orientado a
grafo.

Figura 2.12: Modelo de dados no Neo4j (Neo4j, 2012).

No exemplo da Figura 2.10, existem vrios ns (nmeros 1, 2, 3, 7 e 13) e


relacionamentos dirigidos declarando que uma pessoa conhece a outra, se esse

41
conhecimento pblico ou secreto e o tempo em que se conhecem. Os ns possuem como
propriedade um nome, as relaes tm propriedade que descrevem o tempo que as pessoas
se conhecem e dirigido declarando que uma pessoa sabe da outra e se o conhecimento
publico ou no.

2.2.7.2 Download e instalao


Neo4j pode ser baixado diretamente do site oficial http://www.neo4j.org/install . H
verses para Linux, Mac e Windows.
Depois de baixar, basta extrair e executar. necessrio ter o java instalado.
root@note-ivan# tar -xzvf neo4j.tar.gz
root@note-ivan# cd neo4j
root@note-ivan:/neo4j# ./bin/neo4j start
Apesar do Neo4j requerer java para ser executado, o acesso pode ser feito de
qualquer aplicao que permita a comunicao HTTP, isso porque vem com uma interface
REST.

acesso

pode

ser

feito

pelo

navegador

atravs

do

endereo

http://localhost:7474/webadmin . A partir da interface grfica pode ser realizado todo


gerenciamento do banco de dados, como incluso e remoo de ns e relacionamentos.

2.3 COMPARATIVO ENTRE OS BANCOS DE DADOS NOSQL


Aps o estudo dos bancos de dados NoSQL, apresentado nesta seo uma tabela
comparativa sobre alguns itens. A comparao leva em considerao para quais sistemas
operacionais tm-se pacotes de instalao disponveis, o tipo de licena, o design da
arquitetura, o modelo de dados utilizado, como os dados so armazenados, como possvel
escalar ou replicar e como pode ser executado. Na Tabela 2.1 pode-se visualizar o quadro
comparativo entre os bancos de dados NoSQL.

42
Ano Desenvol- Sistema Licena
vedor
Operacional
2009 Salvatore
Sanfilippo

Redis

2010 Basho
Tecnologies

Riak

2008 Desenvolvido pelo


Facebook.
Cassandra
Mantido por
ASF
2009 ASF

HBase

2005 Damien
Katz (ex
IBM).
Mantido por
CouchDB
ASF

2007 10gen

MongoDB

Neo4j

2007 Neo
Technology

Linux,
BSD
Mac OS e
Solaris

Arquitetura

Modelo Armazenade dados


mento

No distribuida. Chave /
um servidor de
valor
estrutura de dados.
Dados podem ser
replicados em
master / slave
Distribuda. Ns
Chave /
fsicos compostos valor
de ns virtuais, os
vnodes. Dados
distribuidos
automaticamente no
cluster. Fcil adio
de mquinas

Em memria
RAM.
Snapshots em
disco para
durabilidade

Execuo

Gerenciamento
atravs de
programas
clientes em C,
C++, Java, entre
outros.
Linux,
Apache
Em disco.
API HTTP /
Mac OS e 2.0
Buckets com REST. Cliente
Solaris
pares chave / Erlang nativo
valor.
ou clientes em
diversas
linguagens de
programao,
como java, php
e C.
Linux,
Apache Arquitetura
Orientado Configurvel Apache Thrift
Windows 2.0
distribuida. Possvel a colunas armazenament para acesso em
adicionar ns ao
o em disco ou muitas
cluster. Replicao
memria
linguagens.
de dados entre os
ns.
Linux
Apache Roda sobre o
Orientado Configurvel
2.0
HDFS. Suporta
a colunas armazenament
tanto arquitetura
o em disco ou
totalmente
memria
distribuda, como
independente
Linux,
Apache Arquitetura
Orientado Documentos Oferece API
Mac OS e 2.0
distribuda com
a
JSON em
REST/HTTP.
Windows
replicao
documen- disco, rvores Tambm um
bidirecional
tos
B para
gerenciador
(sincronizao) dos
indexar.
web chamado
dados.
Mantm
Futon
verses.
Windows, AGPL
Cliente / servidor. Orientado Coleo de
Drivers oficiais
Mac OS
Servio mongos a
documentos disponveis para
X, Linux
define para qual
documen- armazenados C, C++,
e Solaris
servidor enviar
tos
no disco,
Haskell, Java,
requisio. Dados
organizados JavaScript, Perl,
distribudos
em forma
PHP, entre
automaticamente
rvore B
outros
entre os ns.
Linux,
GPLv,
Replicao dos
Orientado
API REST e
Mac e
AGPL e dados master / slave a grafos
gerenciamento
Windows comercial
web
Tabela 2.1: Tabela comparativa NoSQL Databases.

43

Pelos estudos realizados e pela Tabela 2.1 de comparao, possvel identificar que
a maioria dos bancos de dados NoSQL testados so suportados pelos principais sistemas
operacionais. A maioria deles tambm possui uma arquitetura distribuda, ou seja, esto
presentes em vrios ns no mesmo servidor, ou em servidores distintos.
Em relao ao armazenamento, alguns so simples pares de chave/valor, enquanto
outros possuem uma estrutura mais complexa, como o caso do Neo4j. medida que as
estruturas tornam-se mais complexas pode-se acabar tendo perda de desempenho na escrita
dos dados.
Quanto ao gerenciamento, alguns possuem gerenciamento web nativo, enquanto a
maioria pode ser acessada por clientes padres no shell ou atravs de bibliotecas para as
diversas linguagens de programao.
No captulo seguinte, ser descrito a escolha de um dos bancos de dados estudados,
os motivos que levaram a esta escolha e a proposta de desenvolvimento de uma aplicao,
que outro objetivo deste trabalho.

44

3 PROPOSTA DO TRABALHO

Neste captulo apresentada a proposta para o desenvolvimento de uma aplicao


que utilizar um dos Bancos de Dados NoSQL estudados. A aplicao serve para consultar,
inserir, alterar e remover objetos da base de dados, demonstrando o funcionamento em um
sistema real.

3.1 PROPOSTA DE DESENVOLVIMENTO


A aplicao desenvolvida tem com objetivo o acesso a um banco de dados NoSQL,
efetuando consultas, inseres, edies e remoes de registros da base de dados.
Para o desenvolvimento da aplicao foi escolhido o Banco de Dados MongoDB. A
escolha deu-se pelo fato do MongoDB ser um banco de dados relativamente fcil de ser
instalado e de simples entendimento, ideal para quando se est iniciando em projetos com
Banco de Dados NoSQL. Inclusive pode ser recomendado para quem est fazendo uma
transio de bancos de dados relacionais para NoSQL.
Outros pontos levados em considerao que o banco de dados escolhido deveria ser
gratuito, preferencialmente sob uma licena open source, estar disponvel para Sistema
Operacional Linux e possuir pacotes para os outros sistemas operacionais seria um
diferencial. Alm disso, MongoDB trabalha com documento BSON, que so documentos
como JSON, porm guardados em forma binria. Estes documentos so um formato leve e
rpido de intercmbio de dados, sendo inclusive tratados como sucessor do XML. E, por
fim, a documentao existente no site oficial tambm bastante completa, o que excelente

45
para comear o estudo de uma nova tecnologia e, h alguns livros sobre o assunto.
A aplicao foi desenvolvida na linguagem de programao Java, com interface
grfica. Para o desenvolvimento do cdigo e a interface grfica foi utilizado o software
NetBeans IDE 7.1 e a interface grfica utiliza a ferramenta Swing. Alm disso, utilizado o
driver para Java para comunicao entre cliente e servidor. Tanto o driver como a
documentao encontram-se disponveis no site oficial do MongoDB. O driver est sob a
licena Apache.
A aplicao consiste em um Repositrio de Monografias, onde um usurio poder
acessar, visualizar as informaes e efetuar o download do arquivo com a monografia. As
inseres, edies e remoes estaro a cargo de um administrador.
Cada monografia conter os metadados ilustrados na Figura 3.1:

Figura 3.1: Modelo documento dos metadados

Estes metadados so includos como um novo documento referente ao valor da chave


metadata do documento padro criado pelo MongoDB para suportar arquivos anexos. Isto
pode ser visualizado na Figura 3.2.

Figura 3.2: Documento inserido na coleo "files"

Este documento da Figura 3.2 inserido na coleo files. O MongoDB quebra o

46
arquivo anexo em vrias partes e cada uma delas inserida como um documento na coleo
chunks, como pode ser visto na Figura 3.3.

Figura 3.3: Modelo documento na coleo "chunks".

importante ressaltar que este procedimento de quebra, ou sharding, realizado


automaticamente pelo MongoDB. Ao administrador cabe somente a edio dos metadados
da Figura 3.1.

3.2 DIAGRAMA DE CASOS DE USO


Nesta seo apresentado o diagrama de caso de uso do aplicativo a ser
desenvolvido. A Figura 3.4 mostra o diagrama.

Figura 3.4: Diagrama de caso de uso da aplicao.

A aplicao dividida em duas partes, possui a parte que acessada por qualquer
usurio cliente e a parte que somente o administrador tem acesso, mediante autenticao no

47
banco de dados.
Nas subsees a seguir so especificados os casos de uso referidos no diagrama da
Figura 3.4. Para efetuar as as tarefas como Usurio basta ter acesso sem autenticao, para
acesso como Administrador preciso autenticar-se na base de dados. Portanto, o servidor do
banco de dados deve ter sido inicializado com opo de autenticao. Alm disso, um
usurio com permisso de escrita tambm deve ter sido criado anteriormente. Esses detalhes
no fazem parte da implementao, portanto no sero detalhados.

3.2.1 Especificao do caso de uso Consultar banco de dados


Na tela inicial, apresentado ao usurio a opo consultar o banco de dados, isto ,
buscar registros (documentos) que foram adicionados anteriormente. H uma caixa de texto
para o usurio digitar uma palavra-chave para busca e uma caixa de seleo informando as
opes disponveis para a busca. possvel buscar pelo campo Autor, Orientador ou Ttulo.
Ao clicar no boto de buscar gerada uma lista, disposta em uma tabela, dos registros
encontrados. Na tabela consta apenas alguns metadados do documento (Ttulo, Autor,
Orientador e Ano). Neste momento, tem-se a diferenciao entre Usurio Cliente e
Administrador. Caso esteja conectado como Usurio Cliente, estaro disponveis as opes
para visualizao completa das informaes dos metadados, atravs do boto Detalhar, e
tambm a opo para descarregar o arquivo em PDF da monografia referida. Caso esteja
autenticado como Administrador, estaro disponveis as opes de visualizar os metadados,
pelo boto Detalhar, editar metadados, atravs do boto Editar, e excluir o documento,
atravs do boto Excluir. Ainda na tela de Administrador, este poder realizar uma consulta
avanada atravs de um cone que dar acesso a uma caixa de texto onde dever ser escrita
a consulta baseada em documento.

3.2.2 Especificao do caso de uso Visualizar metadados do documento


Fazendo uma busca com algum critrio de pesquisa, gera-se uma lista com os
documentos encontrados. Esta consulta pode ser realizada tanto a partir da tela de Usurio
cliente quanto da tela de Administrador. A partir deste momento, tanto Usurio Cliente
como Administrador, podem selecionar um elemento da lista e clicar no boto Detalhar.

48
Isso faz com que uma nova janela seja aberta, fornecendo as informaes de todos os
metadados do documento, incluindo Ttulo, Autor, Orientador, Tipo, Ano, Semestre e
Resumo.

3.2.3 Especificao do caso de uso Inserir documento


Aps autenticado como Administrador, a tela mostra uma nova opo, que a
insero de um novo documento. Isto est disponvel atravs de um cone com a legenda
Inserir Monografia. Aps clicar no cone Inserir Monografia uma nova janela aberta
solicitando que os metadados da monografia sejam informados (Ttulo, Autor, Orientador,
Tipo, Ano, Semestre, Resumo) e, tambm, a opo para selecionar o arquivo PDF da
monografia. Para no ocorrer a insero de arquivos PDF iguais, realizada uma
verificao do valor hash gerado a partir do arquivo PDF. Efetua-se a busca para averiguar
se este arquivo j est na base de dados.
Caso a incluso ocorra com xito, a janela fechada e uma mensagem de sucesso
mostrada ao Administrador. Entretanto, ocorrendo um erro durante o procedimento de
insero, este informado ao usurio para que examine as causas.

3.2.4 Especificao do caso de uso Alterar documento


Autenticado como Administrador, na tela de consulta, aps a seleo de elemento da
lista, clica-se no boto de Editar, uma nova janela ser aberta, onde ser possvel alterar
os metadados do documento.
Em cenrio normal, os dados so enviados para a o banco e atualizados, entretanto,
caso ocorra um erro durante o processo ser exibida uma mensagem ao usurio.

3.2.5 Especificao do caso de uso Remover documento


possvel remover registros a partir da tela de Administrador. Aps efetuar uma
consulta, possvel selecionar um item listado e proceder a remoo atravs do boto
Excluir. Havendo sucesso na remoo, mostrada uma mensagem de operao realizada
com sucesso. Caso ocorra algum erro na remoo, exibida uma mensagem de alerta.

49

4 DESENVOLVIMENTO DA APLICAO
Neste captulo discutida a implementao da ferramenta de gerenciamento do
repositrio de monografias. Aps isso, ser feito uma anlise do software desenvolvido.
A aplicao foi desenvolvida em Linguagem Java, utilizando o ambiente de
desenvolvimento integrado Netbeans 7.1, com interface grfica utilizando as ferramentas do
Swing. Tambm foi utilizado o driver Java para conexo entre cliente e servidor mongo da
base de dados.
A aplicao foi desenvolvida focando somente na parte do Cliente, entretanto, alguns
pr-requisitos so necessrios do lado do servidor de Banco de Dados. Entre estes, podemos
destacar a inicializao do servidor com o parmetro para possibilitar autenticao e a
criao de um usurio e senha, com permisso de escrita no Banco de Dados onde sero
armazenadas as monografias. Estas particularidades no sero detalhadas porque no fazem
parte do escopo da aplicao.
O diagrama de classes apresentado na Figura 4.1 mostra a organizao da aplicao.
Os atributos foram suprimidos para simplificar o diagrama.

4.1 CLASSES IMPLEMENTADAS


Nesta seo apresentado o diagrama de classes da aplicao desenvolvida.

50

Figura 4.1: Diagrama de classes da aplicao.

51

Nas subsees a seguir so apresentadas as classes do diagrama de classes e suas


principais funcionalidades.

4.1.1 Classe BuscaDocumento e Classe BuscaDocAdm


Estas classes implementam as interfaces da tela de Usurio Cliente e da tela principal
do Administrador, respectivamente. Foram colocadas nesta mesma subseo porque so
classes semelhantes e utilizam os mesmos mtodos de consulta ao MongoDB.
O primeiro mtodo a ser chamado na aplicao o de conexo com o banco de
dados, que pode ser visualizado na Figura 4.2. Atravs deste mtodo criada uma conexo
com o banco que sem mantm ativa durante o perodo de atividade no banco.

Figura 4.2: Cdigo do mtodo conectar.

As consultas simples realizadas no painel de busca em qualquer uma das duas


interfaces passam por um mtodo para a formatao da consulta, isso porque a query a ser
passada ao banco deve ter a sintaxe de documentos BSON. Na Figura 4.3 temos o cdigo
do mtodo responsvel pela correta formatao da consulta a ser enviada ao banco.

Figura 4.3: Trecho do cdigo do mtodo formataConsulta.

52
O mtodo formataConsulta recebe uma chave (Autor, Orientador ou Titulo) e um
valor como parmetros e o retorno do tipo BasicDBObject, que a instncia no driver
Java para a criao de um documento com sintaxe BSON. O retorno ento passado como
parmetro ao mtodo consultaBanco, como pode ser visualizado na Figura 4.4.
O mtodo consultaBanco recebe uma query baseada em documento para consulta
no MongoDB. A consulta realizada e se houver retorno, estes so inseridos na tabela de
resultado da consulta, vistos nas interfaces de cada classe de busca.
Ao utilizar a opo de consulta avanada disponvel na tela de interface de
Administrador, a query passada diretamente como parmetro ao mtodo consultaBanco,
porque a sintaxe j est formato de documentos BSON.

Figura 4.4: Cdigo do mtodo consultaBanco.

Na interface da tela de Usurio, esto disponveis botes para pesquisar ou visualizar


detalhes dos metadados das monografias e, tambm, o boto para descarregar a monografia.
J na interface da tela principal de Administrador esto disponveis botes para editar
metadados, inserir e excluir monografia e para realizar consultas avanadas.
O mtodo para excluir monografias est implementado na classe BuscaDocAdm.

Figura 4.5: Cdigo do mtodo excluir.

53
A Figura 4.5 mostra o cdigo do mtodo para excluso. O mtodo simples, ele
recebe o identificador de uma monografia selecionada e executa o mtodo remove que
est disponvel na API do MongoDB.

4.1.2 Classe NovoDocumento


Esta classe implementa a interface da tela de insero de monografias e os mtodos
utilizados para tal. As monografias a serem inseridas so obtidas atravs da captura dos
metadados digitados na tela e da seleo do arquivo PDF de uma fonte local (disco rgido).

Figura 4.6: Cdigo do mtodo insereDoc.

Na Figura 4.6 tm-se o cdigo do mtodo responsvel pela insero da monografia.


Os pares chave/valor so capturados a partir da interface e formatados para um documento
de metadados. O arquivo PDF selecionado e o MongoDB, atravs do mtodo createFile,
gera um documento especfico com alguns campos padres, como o visto na Figura 3.2.
O documento com os metadados capturados anteriormente definido como valor da
chave metadata, s ento a monografia em si guardada no Banco de dados atravs do
mtodo save.

54
4.1.3 Classe EditarDocumento
A classe EditarDocumento implementa a interface da tela de alterao dos
metadados das monografias e o mtodo responsvel por isso.
Para editar os metadados de uma monografia armazenada no MongoDB utilizado o
mtodo editarMetadados, que tm um trecho do seu cdigo demostrado na Figura 4.7.

Figura 4.7: Cdigo do mtodo editarMetadados.

O mtodo recebe a identificao do documento a ser editado e um novo documento


de metadados atualizado, que ser substitudo no valor da chave metadata. No driver
Java, h o mtodo findOne, que retorna o documento correspondente ao valor passado como
parmetro. Aps definir os novos metadados, guardado novamente na base de dados.

4.1.4 Classe VisualizarDetalhes


A classe VisualizarDetalhes implementa a interface da tela para visualizar os
metadados completos de uma monografia.
Nesta classe no foram criados mtodos especficos, apenas foram gerados os
mtodos padres (get e set) para setar os valores dos campos na inicializao dos
componentes.

4.1.5 Classe TableModelDoc e Classe Metadado


As classes TableModelDoc e Metadado implementam, respectivamente, a
interface da tabela de Resultado de Busca nas telas de Usurio Cliente e Administrador, e o
tipo de dado que a compe. Ainda na classe TableModelDoc so implementados os
mtodos para manipulao dos elementos na tabela, como incluir, excluir e selecionar. Estes

55
mtodos no executam nenhuma ao no MongoDB, somente na tabela. Por exemplo,
quando procedemos uma consulta na base de dados, o mtodo incluir chamado para que
cada resultado seja includo na tabela e mostrado para o usurio.

4.2 UTILIZAO DA APLICAO


A aplicao desenvolvida atende a dois tipos de usurios, o Usurio Cliente e o
Usurio Administrador, permitindo ao usurio cliente buscar, visualizar metadados e
descarregar a monografia, e ao Administrador consultar, visualizar os metadados, editar os
metadados, remover e inserir monografias no Banco de Dados MongoDB.
Para seguir uma ordem de execuo normal do aplicativo, primeiramente, ser
mostrada a utilizao da aplicao para Usurio Cliente, que a primeira tela a ser
visualizada na aplicao. Posteriormente, ser mostrado o uso a partir da tela principal de
Administrador.

4.2.1 Utilizao como Usurio Cliente


A primeira tela a ser exibida quando a aplicao executada est exposta na Figura
4.8. Na figura, para melhor explicao, foram dispostos nmeros de 1 a 8 para enumerar as
aes disponveis para o usurio. Estes nmeros no se encontram na aplicao, somente na
imagem.
Detalhando as aes, na sequncia, o nmero 1 (cone Administrador), indica a
ao do usurio para autenticar-se como Administrador e ter acesso s opes avanadas.
Aps clicar no cone Administrador, solicitado nome de usurio e senha, anteriormente
criados, como pode ser visualizado na Figura 4.9.

56

Figura 4.8: Tela principal Usurio Cliente.

Figura 4.9: Tela de Autenticao como Administrador.

57
Seguindo com as aes do usurio da Figura 4.8, o nmero 2 indica a ao para o
usurio sair do sistema. J o nmero 3 mostra o campo onde digitado o valor a ser
buscado e, no nmero 4 informado onde deseja buscar, se em Autor, Orientador ou
Ttulo. No exemplo da Figura 4.8 foi informado o valor maria a ser buscado na chave
Orientador. Aps informar os dados de busca, a consulta realizada clicando-se no boto
Pesquisar, referenciado pelo nmero 5; isto faz com que uma tabela com os registros
encontrados seja gerada abaixo do rtulo Resultado da busca. Lembrando que, para obter
sucesso na busca, necessrio que monografias tenham sido inseridas anteriormente. Na
prxima subseo mostrado como inserir monografias. Caso o usurio queira buscar outro
valor, basta repetir o procedimento a partir do nmero 3, sendo tambm possvel limpar a
tela de busca clicando no boto Limpar, visto ao lado do nmero 6.

Figura 4.10: Tela de Visualizao dos Detalhes.

As ltimas aes disponveis na tela de busca do usurio, so os botes Detalhar,


referenciado pelo nmero 7, e Descarregar, visto no nmero 8. Para executar ambas
aes, antes preciso selecionar um item na tabela gerada pela busca. Feito isto, ao clicar
em Detalhar, uma nova tela com todos os metadados da monografia para visualizao e

58
leitura. A tabela resultante da consulta possui apenas alguns metadados; para a visualizao
completa dos detalhes preciso seguir os passos mencionados. Na Figura 4.10 pode ser
visualizada a tela gerada ao selecionar um item da tabela e clicar em Detalhar. Nesta tela,
nenhuma alterao de metadados possvel, pois os campos esto desativados para edio.
Por ltimo, ao selecionar um item da tabela resultante da busca e clicar no boto
Descarregar, possvel fazer download da monografia selecionada, selecionando o local
do disco onde se deseja armazenar a monografia em PDF.

4.2.2 Utilizao como usurio Administrador


Aps iniciar a execuo da aplicao, e autenticar como Administrador, conforme
indicam as Figuras 4.8 e 4.9, tem-se acesso a tela principal de Administrador com opes
avanadas, que permitem incluir e excluir monografia, editar metadados e realizar consultas
avanadas na base de dados. A Figura 4.11 mostra como a tela de Administrao.
Da mesma maneira do captulo anterior, foram adicionados nmeros (1 a 4) para
melhor referenciar as aes que o administrador pode tomar. Algumas aes, como a busca
simplificada por Autor, Orientador ou Ttulo, e do boto Detalhar, so as mesmas que
foram utilizadas no captulo anterior, e funcionam da mesma maneira na tela de
Administrador, portanto no sero explicadas novamente.

59

Figura 4.11: Tela principal do Administrador.

Os nmeros adicionados imagem indicam, em sequncia, o cone da ao para


Consulta Avanada (1), o cone de Insero de Monografias (2), o boto para Edio dos
Metadados (3) e o boto de Excluso de Monografia (4). Nas prximas subsees so
detalhados os resultados obtidos atravs de cada ao.

60
4.2.2.1 Insero de monografias no MongoDB
Atravs da tela principal de Administrador, exposta na Figura 4.11, o Administrador
pode clicar sobre o cone Inserir Monografia, identificado naquela figura pelo nmero 2.
Feito isto, exibida a tela de insero de monografia, mostrada na Figura 4.12. Atente que
na figura j constam os dados preenchidos para insero, mas a tela inicializada com os
campos vazios.

Figura 4.12: Tela de Insero de Monografias.

Nesta tela, o administrador informa os metadados relativos monografia a ser


inserida, juntamente com o arquivo em formato PDF da monografia. Com os campos
preenchidos, ao clicar no boto Inserir so gerados dois documentos, um relativo aos
metadados (Titulo, Autor, Orientador, Tipo, Ano, Semestre e Resumo) e outro com algumas
informaes do arquivo PDF selecionado. O documento gerado para o arquivo PDF uma
propriedade do prprio MongoDB, atravs da ferramenta GridFS, j comentado

61
anteriormente neste trabalho. Para entender melhor, pode-se visualizar na Figura 4.13 como
fica definido para o arquivo que estamos incluindo.

Figura 4.13: Documento gerado na insero da monografia.

Existem dois pontos chaves na insero, o documento com os metadados inserido


como valor na chave metadata, portanto um documento dentro de outro documento.
importante ter conhecimento disso para as consultas avanadas que sero realizadas na
sequencia. Outro ponto importante a chave md5, que nica para cada arquivo PDF.
Portanto, ao clicar no boto Inserir chamado um mtodo de verificao dessa chave
md5, caso ela j conste na base de dados a monografia no ser inserida, pois isso
significa que o arquivo PDF j est na base de dados.

4.2.2.2 Execuo de consultas avanadas no MongoDB


Aps a insero de monografias terem sido realizada com sucesso, possvel
consult-las atravs de busca simplificada como a realizada na subseo 4.2.1 tanto como
usurio cliente ou como administrador. Ou, a partir da tela de administrador possvel a
realizao de consultas avanada baseadas em documento.
A partir da tela principal de Administrador, ao clicar no cone Consulta Avanada,
indicada pelo nmero 1 na Figura 4.11, aberta uma caixa de texto como a visualizada na
Figura 4.14, onde possvel escrever a consulta a ser realizada.

62

Figura 4.14: Caixa de texto para consulta avanada.

Para realizar a consulta, o administrador precisa recordar do modelo de documento e


metadados que so construdos no momento de insero da monografia. Portanto, como
informado anteriormente, no documento gerado ao inserir uma monografia est presente
uma chave chamada metadata contendo como valor um documento com os metadados.
Ento,

as

consultas

usaro,

na

maioria

das

vezes,

sintaxe

metadata.CHAVE_DOC_METADADO, onde CHAVE_DOC_METADADO a chave


contida no documento dos metadados (Titulo, Autor, Orientador, Tipo, Ano, Semestre ou
Resumo).
Assim, as consultas seguem o modelo baseado em documento, exigindo a mesma
sintaxe de um documento BSON, iniciando e fechando com o caractere chaves ( { }) e
passando pelo menos um par chave/valor a ser buscado. No MongoDB esto disponveis
operadores especiais de consulta, como operadores de comparao, operadores lgicos, etc.
No endereo http://docs.mongodb.org/manual/reference/operators/#query-selectors h uma
lista dos operadores disponveis e o significado de cada um deles.
A seguir so mostrados exemplos de algumas consultas que podem ser realizadas na
base de dados atravs da aplicao desenvolvida.
Consultar as monografias defendidas no ano de 2012:
{ "metadata.Ano" : "2012" }
Buscar todas monografias defendidas no primeiro semestre, incluindo todos os
anos.

63
{ "metadata.Semestre" : "1" }
Consultar as monografias defendidas no ano de 2012, no segundo semestre:
{"metadata.Ano": "2012", "metadata.Semestre": "2" }
A consulta anterior pode ser realizada de outra maneira, usando o operador $and,
desta forma, se a primeira expresso avaliada como falsa, as expresses restantes no
sero avaliadas:
{ $and: [ {"metadata.Ano" : "2012"}, {"metadata.Semestre": "2" } ] }
Consulta para retornar as monografias defendidas entre o ano de 2008 e 2011,
incluindo os anos mencionados.
{"metadata.Ano": {$gte: "2008", $lte: "2011"} }
Consultar monografias realizadas antes de 2010:
{"metadata.Ano": {$lt: "2010" } }
Buscar todas monografias defendidas , com exceo do ano de 2011.
{"metadata.Ano": {$ne: "2011"}}
Consultar monografias realizadas antes de 2005 ou depois de 2010, excluindo
estes.
{$or: [{"metadata.Ano" : { $lt: "2005" }}, {"metadata.Ano": { $gt:"2010"} } ] }
Buscar as monografias defendidas no ano de 2005, 2010 ou 2012, usando o
operador $in. Para isto passado uma chave e uma lista de valores para consulta.
{"metadata.Ano": {$in: ["2005", "2010", "2012"]}}
Se trocarmos o operador $in pelo operador $nin e realizarmos a mesma consulta
anterior, teremos como resultado todas as monografias, com exceo das defendidas no ano
de 2005, 2010 e 2012.
{"metadata.Ano": {$nin: ["2005", "2010", "2012"]}}
Consultar monografias orientadas por "Maria da Silva".
{"metadata.Orientador" : "Maria da Silva"}

64

Consultar monografias que tenham como Orientadora "Maria da Silva", no ano


de 2012.
{"metadata.Orientador" : "Maria da Silva", "metadata.Ano" : "2012"}
Consultar todas as monografias orientadas por "Maria da Silva" no ano de 2011,
no primeiro semestre letivo:
{"metadata.Orientador" : "Maria da Silva", "metadata.Ano" : "2011",
"metadata.Semestre" : "1"}
Caso no tenha certeza do nome completo do Orientador, possvel buscar por
apenas um nome ou parte dele, isso possvel com o operador $regex do javascript, que
fornece capacidade para formar expresses regulares para a consulta.
{"metadata.Orientador": {$regex: ".*Maria"}}
ideal que consultas utilizando $regex sejam realizadas combinando o operador
mencionado, com o operador $options e sinalizador "i", para no haver diferenciao entre
letras maisculas e minsculas. Um exemplo para esta consulta.
{"metadata.Orientador" : {$regex:".*maria", $options: "i"} }
Consultar monografias que contenham a string "lucas" em Autor e primeiro
semestre.
{ "metadata.Autor": { $regex: ".*lucas", $options: "i" }, "metadata.Semestre":
"1"}
Os resultados encontrados so listados na tabela Resultado da Busca, onde
possvel selecionar um elemento da tabela para visualizar, editar metadados ou excluir a
monografia. O procedimento para estas aes ser mostrado na prxima subseo.

4.2.2.3 Edio de Metadados de Monografias no MongoDB


Com as monografias j inseridas na base de dados, possvel fazer alteraes nos
metadados destas. A partir da tela principal de Administrador e aps a realizao de uma
consulta aplicando os filtros necessrios, os resultados gerados e mostrados na tabela de

65
busca esto disponveis para alterao. Para proceder a edio, basta selecionar um item da
tabela e clicar sobre o boto Editar, indicado pelo nmero 3 na Figura 4.11. Ao clicar
neste boto, uma nova tela ser aberta, como pode ser visualizado na Figura 4.15

Figura 4.15: Tela de Edio de Monografias.

Os metadados relativos monografia selecionada so carregados automaticamente


na tela de edio, basta editar quais campos forem necessrios e clicar no boto Salvar
para concluir a edio. Ao fazer isso, um novo documento com os metadados criado que
substituir o documento antigo.
Importante ressaltar que o arquivo PDF da monografia no pode ser alterado, caso
seja preciso alterao deste, o procedimento padro a seguir a excluso da monografia e a
insero de uma monografia com o arquivo PDF. Nenhum campo pode estar vazio, se isso
acontecer no ser permitido salvar a edio.

66
4.2.2.4 Excluso de monografias no MongoDB
O MongoDB facilita muito o processo de excluso de documentos. Ao realizar uma
consulta, a partir da tela principal do Administrador, os resultados so listados na tabela
Resultado da Consulta, como mostra a Figura 4.11. possvel selecionar um item e
proceder a excluso atravs do boto Excluir, indicado naquela mesma figura pelo
nmero 4. Ao clicar neste boto chamado o mtodo para remover o documento,
passando a identificao do documento a ser removido.

4.2.3 Tratamento de erros


Durante os testes foram identificados alguns erros que podem ser cometidos pelos
usurios.
Partindo do princpio da execuo aplicao, ao clicar no boto Detalhar ou
Descarregar na tela de Usurio Cliente e no ter selecionado um item na tabela de
resultados, um aviso ser passado ao usurio sobre a necessidade de selecionar um elemento
para detalhar ou descarregar. Outro possvel erro pode ocorrer no momento da autenticao
para acessar a tela de Administrador. Caso seja sejam digitados usurio ou senha incorretos
uma mensagem de aviso ser fornecida ao usurio. Outro aviso ser fornecido ao usurio
caso seja tentado realizar uma consulta passando menos de 3 caracteres, pois isto no
permitido.
J na tela principal de Administrador, podem ocorrer erros ao tentar editar metadados
ou excluir monografia sem a prvia seleo de um item da tabela. Um aviso ser fornecido
ao administrador para que ele primeiro selecione um elemento e somente ento execute
alguma ao.
Ainda na tela de administrador, ao tentar inserir uma nova monografia e no ter
completado todos os metadados, ser informado ao administrador para que isto seja
corrigido, pois todos os campos so obrigatrios. Este mesmo erro pode acontecer na tela de
edio de metadados, onde tambm comunicado ao administrador para que complete as
informaes. Outro erro que pode acontecer ao inserir uma nova monografia se o arquivo
PDF informado j existe na base de dados. Antes da insero realizada uma verificao
atravs da hash gerado a partir do arquivo, caso o arquivo j exista, no ser possvel inserir
a monografia e o administrador ser avisado para que corrija a situao.

67
4.3 TESTES DE DESEMPENHO
Nesta subseo demonstrado um conjunto de testes de carga de dados que foram
realizado, objetivando verificar a escalabilidade do banco e da aplicao na insero de
dados. Os testes baseiam-se na insero de monografias e a captura do tempo para tal
realizao. Uma pequena modificao momentnea foi realizada na aplicao para permitir
a insero de monografias idnticas, isso foi feito para que ocorresse a insero de
monografias de mesmo tamanho e que a escrita dos dados no disco no proporcionasse uma
falsa anlise. Os testes foram realizados utilizando-se um computador porttil com Intel(R)
Core(TM) i5 CPU M480 at 2.67GHz, com 4 processadores, 4GB de memria e rodando
Ubuntu 10.04 de 32 bits.
A tabela 4.1 mostra os testes de inseres que foram realizados.
N de
monografias
inseridas

Tamanho PDF
(Kilobytes)

Tempo
(segundos)

1,5

0,002

15

0,005

1,5

0,014

15

0,028

1,5

0,085

15

0,153

1,5

0,31

15

0,659

1,5

2,69

15

4,68

1,5

18

15

43,42

500.000

1,5

72,5

1.000.000

1,5

134,6

1
10
100
1.000
10.000
100.000

Tabela 4.1: Carga de inseres na base dados.

A carga de dados da Tabela 4.1 busca ratificar os argumentos de que os bancos de


dados NoSQL proporcionam bom desempenho (Strauch, 2011) . Nos testes foram inseridas
monografias com arquivos PDF de tamanho 1,5KB e 15KB para mostrar que existe uma

68
grande diferena ao incluir a mesma quantidade de monografias, porm com arquivos PDF
de tamanhos distintos. Esse fato fica evidente na tabela, onde mostra que o tempo para
realizar a insero da mesma quantidade de monografias foi praticamente o dobro (com
uma pequena variao) para arquivos de tamanho 15KB em comparao com os arquivos de
1,5KB. Isso deve ser levado em considerao na anlise de desempenho e tambm em
comparaes com outros SGBDs. Ainda sobre os testes, foram inseridas desde uma
monografia, at 1.000.000 de monografias. As inseres de 500.000 monografias e
1.000.000 monografias foram realizadas somente com arquivos de 1,5KB pois estvamos
trabalhando com sistema de 32 bits e o limite de 2GB era superado nos arquivos de 15KB,
restrio esta detalhada na reviso de literatura do captulo 2.2.6.
Um outro ponto que deve ser ressaltado que o tempo consumido na insero de
grandes quantidades de documentos no tem aumento linear. Pode ser visto na mesma
tabela que a insero de 1.000.000 de arquivos de 1,5KB e seus metadados demora 134,6
segundos. Se esse tempo for dividido por 1.000 chega-se ao resultado de um tempo mdio
de 0,135 segundos para cada 1000 inseres, tempo este bem abaixo dos 0,31 segundos
registrados na insero de 1000 documentos realizados na carga anterior.
Alm dos pontos ressaltados, outra questo importante a escalabilidade horizontal
que pode ser realizada para suprir deficincias de hardware como neste caso, onde a escrita
em disco comprovadamente um problema. No caso dos testes realizados, se estivssemos
trabalhando com outros servidores e utilizando vrias instncias do MongoDB a tarefa de
escrita em disco seria dividida entre estes servidores, diminuindo assim o tempo gasto para
escrita de dados. No foram efetuados testes nesse sentido, mas as referncias bibliogrficas
apontam que o ganho de desempenho considervel ao utilizar mltiplas instncias do
Mongo. O MongoDB fornece nativamente o recurso de sharding automtico, muito til para
escalabilidade horizontal, onde os arquivos so divididos em partes pequenas e podem ser
armazenadas em um ou mais servidores.

4.4 DOWNLOAD DA APLICAO


Os cdigos fonte da aplicao e o arquivo para instalao do MongoDB esto
disponveis em http://www.inf.ufsm.br/~ivanf/MongoDB. Antes de executar a aplicao
recomendvel conferir se o Java est instalado no computador e qual a verso. A aplicao
foi desenvolvida utilizando o Java 7, s funcionar a partir desta verso.

69

5 CONCLUSES E TRABALHOS FUTUROS


A finalidade deste trabalho foi fornecer uma viso geral e introduzir ao movimento
dos NoSQLs Databases, que surgiu com fora nos ltimos anos, sendo uma alternativa aos
SGBD predominantemente relacionais. Para isto, um dos objetivos foi analisar alguns
bancos de dados NoSQL disponveis para utilizao e que j tinham uma certa
popularidade. Foram analisados os bancos Redis, Riak, Cassandra, Hbase, CouchDB,
MongoDB e Neo4j. Atravs da anlise foi possvel obter embasamento para a necessidade
de trabalhar com uma base de dados no relacional.
O estudo desenvolvido sobre os NoSQL Databases teve a inteno de adquirir
conhecimentos sobre como cada um deles funciona, de que forma os dados so
armazenados, qual a arquitetura que cada um deles utiliza, quais os requisitos para o
funcionamento, se so proprietrios ou open source e tambm para compreender e propagar
tecnologias que so conceitualmente distintas das tradicionais e que esto em grande
crescimento, com o intuito de proporcionar alternativas de escolha e fundamentao no
momento de optar como os dados de um sistema sero armazenados.
Aps a realizao dos estudos sobre os NoSQL Databases, um deles foi escolhido,
levando em considerao as informaes obtidas na anlise individual, para o
desenvolvimento de uma aplicao. O Banco de Dados escolhido foi o MongoDB, e as
razes que levaram escolha do referido banco foram discutidas no captulo 3 deste
trabalho. Aps a escolha do banco, foi proposto o desenvolvimento da aplicao para a
manipulao dos dados armazenados neste banco de dados.
A aplicao proposta foi desenvolvida na linguagem de programao Java e o
principal objetivo dela gerenciar o contedo de uma base de dados. Com a utilizao desta

70
aplicao, possvel armazenar, na base de dados do MongoDB, arquivos de monografias,
incluindo seus metadados, em forma de documentos BSON, tambm possvel edit-los,
remov-los e consult-los. Nos exemplos e nos testes da aplicao foram utilizados
documentos que procuraram ser fidedignos aos metadados encontrados nas monografias dos
cursos de graduao atuais.
Como sugesto para trabalhos futuros, indica-se a transcrio da aplicao
desenvolvida neste trabalho para alguma linguagem de programao para web, tornando a
aplicao mais dinmica, que vem a ser um dos objetivos dos bancos NoSQL. Outra
sugesto que a aplicao possa permitir a incluso de campos extras, se necessrio, nos
metadados. Por exemplo, uma monografia pode ter, alm do orientador, um co-orientador,
enquanto outras no monografias continuariam no necessitando deste campo.
Outro ponto que pode ser includo o cadastro de novos usurios administradores a
partir da tela de Administrador da aplicao.
Por ltimo, sugere-se efetuar a utilizao de vrios servidores para distribuio e
replicao dos dados, efetuando cargas de dados, consulta, edio e excluso para testes de
desempenho a medida que so agregados novos servidores.

71

REFERNCIAS
ANDERSON, J. C.; Lehnardt, J.; Slater, N. CouchDB: The Definitive Guide. Ed. O'Reilly
Media, 2010.
BSON. Binary JSON. Disponvel em http://bsonspec.org/. Acesso em novembro de 2012.
Campanelli,

P.

The

architecture

of

REDIS.

Disponvel

em

http://www.enjoythearchitecture.com/redis-architecture.html. Acesso em novembro de


2012.
Cassandra. The Apache Cassandra database. Disponvel em http://cassandra.apache.org.
Acesso em dezembro de 2012.
Cho,

T.

Apache

Cassandra

Quick

tour.

Disponvel

http://javamaster.wordpress.com/2010/03/22/apache-cassandra-quick-tour/.

Acesso

em
em

dezembro de 2012.
CouchDB. Apache CouchDB. Disponvel em http://couchdb.apache.org/. Acesso em
novembro de 2012.
Datastax.

Apache

Cassandra

Documentation.

http://www.datastax.com/docs/1.1/index. Acesso em dezembro de 2012.

Disponvel

em

72
FindTheBest. Compare NoSQL Databases. Disponvel em http://nosql.findthebest.com/.
Acesso em novembro de 2012.
Hbase. Apache Hbase. Disponvel em http://hbase.apache.org/. Acesso em dezembro de
2012.
HEWITT, Eben. Cassandra: The Definitive Guide. Sebastopol: O'Reilly Media, 2010.
Ho,

R.

MongoDb

Architecture.

Disponvel

em

http://horicky.blogspot.com.br/2012/04/mongodb-architecture.html. Acesso em novembro


de 2012.
Ippolito, Bob. Drop ACID and think about Data. March 2009. Disponvel em.
http://blip.tv/file/1949416/. Acesso em novembro de 2012.
JSON. Introducing JSON. Disponvel em http://www.json.org/. Acesso em novembro de
2012.
Katz,

D.

CouchDb

Architecture.

Disponvel

em

http://damienkatz.net/2005/04/couchdb_archite.html. Acesso em novembro de 2012.


Leavitt, Neal. Will NoSQL Databases Live Up to Their Promise?. Computer. IEEE, New
York,, vol. 43, n. 2, p.12-14, Fev. 2010.
MongoDB.

MongoDB

Docs.

Disponvel

em

http://www.mongodb.org/display/DOCS/Home. Acesso em novembro de 2012.


Neo4j. The Neo4j Manual. Disponvel em http://docs.neo4j.org/chunked/stable/. Acesso
em dezembro de 2012.
Orend, K. Analysis and Classification of NoSQL Databases and Evaluation of their
Ability to Replace an Object-relational Persistence Layer. Master Thesis, Technical
University of Munich, Munich, 2010.

73
Popescu, A. Presentation: NoSQL at CodeMash - An Interesting NoSQL categorization.
Disponvel em http://nosql.mypopescu.com/post/396337069/presentation-nosql-codemashan-interesting-nosql. Acesso em novembro de 2012.
Pritchett, Dan. BASE: An Acid Alternative. Queue. ACM, New York, vol. 6, n. 3, p.48-55,
mai/jun. 2008.
Redmond, E.; Wilson, J. R. Seven Databases in seven weeks - A Guide to Modern
Databases and the NoSQL Movement. Ed. The Pragmatic Programmers, 2012.
Riak. Riak Basho. Disponvel em http://riak.basho.com/. Acesso em novembro de 2012.
Strauch, C. NoSQL Databases. Disponvel em http://www.christof-strauch.de/nosqldbs.pdf.
Acesso em novembro de 2012.
Seguin K. The Little Redis Book. Disponvel em https://github.com/karlseguin/the-littleredis-book. Acesso em novembro de 2012.
Tiwari, S. Professional NoSQL. Ed. Wrox Programmer to Programmer, 2011.
Wikipedia. JSON. Disponivel em http://en.wikipedia.org/wiki/JSON. Acesso em novembro
de 2012.

74

APNDICES

APNDICE A Cdigo fonte da aplicao

A.1

BuscaDocumento.java

package aplicacao;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCursor;
import com.mongodb.Mongo;
import com.mongodb.gridfs.GridFS;
import com.mongodb.gridfs.GridFSDBFile;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import org.bson.types.ObjectId;
public class BuscaDocumento extends javax.swing.JFrame {
static final String HOST = "localhost";
static final int PORTA = 27017;
static final String DB_NAME = "repositorio";
private Mongo mongo;
private DB db;
private GridFS myFS;

75
private TableModelDoc tableModelDoc;
BuscaDocAdm telaBuscaDocAdm;
public BuscaDocumento() {
initComponents();
tableModelDoc = new TableModelDoc();
tableDoc.setModel(tableModelDoc);
tableDoc.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
tableDoc.getColumnModel().getColumn(0).setPreferredWidth(tableDoc.get
Width() / 2);
tableDoc.getColumnModel().getColumn(1).setPreferredWidth(tableDoc.get
Width() / 4);
tableDoc.getColumnModel().getColumn(2).setPreferredWidth(tableDoc.get
Width() / 4);
tableDoc.getColumnModel().getColumn(3).setPreferredWidth(tableDoc.get
Width() / 20);
tableModelDoc.fireTableDataChanged();
conectar(user, pwd);
}
/**
* This method is called from within the constructor to initialize the
form.
* WARNING: Do NOT modify this code. The content of this method is
always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
// </editor-fold>

private void buttonPesquisarActionPerformed(java.awt.event.ActionEvent


evt) {
limparTela();
String busca = tfBusca.getText();
if (busca.length() > 2) {
String buscaCampo = (String) comboBusca.getSelectedItem();
BasicDBObject query = formataConsulta(buscaCampo, busca);
consultaBanco(query);
} else {
JOptionPane.showConfirmDialog(null,
" Digite uma busca com pelo menos 3 caracteres! ", "Alerta!",
JOptionPane.CLOSED_OPTION);
}
}
private void menuSUActionPerformed(java.awt.event.ActionEvent evt) {
jdLogin.pack();
jdLogin.setVisible(true);
}

76
private void buttonDetalharActionPerformed(java.awt.event.ActionEvent
evt) {
// TODO add your handling code here:
detalhar();
}
private void tableDocMouseClicked(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
selecao();
}
private void buttonDescarregarActionPerformed(java.awt.event.ActionEvent
evt) {
// TODO add your handling code here:
try {
baixar();
} catch (IOException ex) {
Logger.getLogger(BuscaDocumento.class.getName()).log(Level.SEVERE,
null, ex);
}
}
private void menuSairActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
System.exit(0);
}
private void tableDocKeyReleased(java.awt.event.KeyEvent evt) {
// TODO add your handling code here:
selecao();
}
private void buttonCancelarActionPerformed(java.awt.event.ActionEvent
evt) {
// TODO add your handling code here:
jdLogin.setVisible(false);
}
private void buttonConectarActionPerformed(java.awt.event.ActionEvent
evt) {
// TODO add your handling code here:
user = tfUsuario.getText();
pwd = new String(pfSenha.getPassword());
boolean autenticacao = conectar(user, pwd);
if (autenticacao) {
telaBuscaDocAdm = new BuscaDocAdm(db, user, pwd);
telaBuscaDocAdm.setVisible(true);
jdLogin.setVisible(false);
dispose();
} else {
JOptionPane.showMessageDialog(null, "Login incorreto!", "Alerta",
JOptionPane.WARNING_MESSAGE);
}
}
private void buttonLimparBuscaActionPerformed(java.awt.event.ActionEvent
evt) {
// TODO add your handling code here:

77

tfBusca.setText("");
limparTela();

private void jmLimparActionPerformed(java.awt.event.ActionEvent evt) {


// TODO add your handling code here:
tfBusca.setText("");
limparTela();
}
private void buttonAdminActionPerformed(java.awt.event.ActionEvent evt)
{

// TODO add your handling code here:


jdLogin.pack();
jdLogin.setVisible(true);
}
private void buttonSairActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
System.exit(0);
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {

//<editor-fold defaultstate="collapsed" desc=" Look and feel setting


code (optional) ">
//</editor-fold>
/*
* Create and display the form
*/
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new BuscaDocumento().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton buttonAdmin;
private javax.swing.JButton buttonCancelar;
private javax.swing.JButton buttonConectar;
private javax.swing.JButton buttonDescarregar;
private javax.swing.JButton buttonDetalhar;
private javax.swing.JButton buttonLimparBusca;
private javax.swing.JButton buttonPesquisar;
private javax.swing.JButton buttonSair;
private javax.swing.JComboBox comboBusca;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JMenuBar jMenuBar1;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JDialog jdLogin;

78
private javax.swing.JLabel jlImgAut;
private javax.swing.JMenuItem jmLimpar;
private javax.swing.JPopupMenu.Separator jsSeparador1;
private javax.swing.JPopupMenu.Separator jsSeparador2;
private javax.swing.JLabel labelResultadoBusca;
private javax.swing.JLabel labelTitulo;
private javax.swing.JMenu menuMenu;
private javax.swing.JMenuItem menuSU;
private javax.swing.JMenuItem menuSair;
private javax.swing.JPasswordField pfSenha;
private javax.swing.JTable tableDoc;
private javax.swing.JTextField tfBusca;
private javax.swing.JTextField tfTituloDoc;
private javax.swing.JTextField tfUsuario;
// End of variables declaration
public javax.swing.JTable getTableDoc() {
return tableDoc;
}
public javax.swing.JTextField getTfTituloDoc() {
return tfTituloDoc;
}
public void setTfTituloDoc(javax.swing.JTextField tfTituloDoc) {
this.tfTituloDoc = tfTituloDoc;
}
boolean conectar(String user, String pwd) {
try {
mongo = new Mongo(HOST, PORTA);
db = mongo.getDB(DB_NAME);
boolean aut = db.authenticate(user, pwd.toCharArray());
if (aut) {
myFS = new GridFS(db);
return true;
} else {
return false;
}
} catch
(Exception e) {
JOptionPane.showConfirmDialog(null,
"No foi possvel conectar-se ao servidor: " + HOST, "Alerta!",
JOptionPane.CLOSED_OPTION);
System.exit(0);
}
return false;
}
// metodo para formatar a string da consulta a ser realizada
private BasicDBObject formataConsulta(String chave, String busca) {
String exprReg = "^.*" + busca + ".*$";
Pattern valor = Pattern.compile(exprReg, Pattern.CASE_INSENSITIVE);
BasicDBObject query = new BasicDBObject("metadata." + chave, valor);
return query;
}
// metodo para consultar o banco de dados,
// retornando uma lista de registros

79
private void consultaBanco(BasicDBObject query) {
try {
DBCursor cursor = myFS.getFileList(query).sort(query);
while (cursor.hasNext()) {
BasicDBObject metadados = (BasicDBObject)
cursor.next().get("metadata");
String mTitulo = (String) metadados.get("Titulo");
String mAutor = (String) metadados.get("Autor");
String mOrientador = (String) metadados.get("Orientador");
String mAno = (String) metadados.get("Ano");
Metadado m = new Metadado(mTitulo, mAutor, mOrientador, mAno);
inserirTable(m);
}
} catch (Exception e) {
System.out.println("Sem resultado...");
}
}
//metdo para selecionar
private void selecao() {
int index = getTableDoc().getSelectedRow();
if (index == -1) {
return;
}
Metadado m = tableModelDoc.selecao(index);
getTfTituloDoc().setText(m.getTitulo());
}
//metodo para inserir o registro na tabela de consulta
private void inserirTable(Metadado met) {
if (met != null) {
tableModelDoc.incluir(met);
}
}
//metodo para chamar uma nova tela para visualizar os detalhes
private void detalhar() {
int index = getTableDoc().getSelectedRow();
System.out.println("index: " + index);
if (index == -1) {
JOptionPane.showConfirmDialog(null,
" Nenhum registro selecionado! ", "Alerta!",
JOptionPane.CLOSED_OPTION);
return;
}
Metadado m = tableModelDoc.selecao(index);
BasicDBObject query = new BasicDBObject("metadata.Titulo",
m.getTitulo());
GridFSDBFile fileout = myFS.findOne(query);
ObjectId id = (ObjectId) fileout.getId();
BasicDBObject metadados = (BasicDBObject) fileout.get("metadata");
String mTitulo = (String) metadados.get("Titulo");
String mAutor = (String) metadados.get("Autor");
String mOrientador = (String) metadados.get("Orientador");
String mTipo = (String) metadados.get("Tipo");
String mAno = (String) metadados.get("Ano");

80
String mSemestre = (String) metadados.get("Semestre");
String mResumo = (String) metadados.getString("Resumo");
VisualizarDetalhes telaVisualizarDoc = new VisualizarDetalhes(id,
mTitulo, mAutor, mOrientador, mTipo, mAno, mSemestre, mResumo);
telaVisualizarDoc.setVisible(true);
}
// metodo para fazer o download do arquivo PDF
private void baixar() throws IOException {
int index = getTableDoc().getSelectedRow();
if (index == -1) {
JOptionPane.showConfirmDialog(null,
" Nenhum registro selecionado! ", "Alerta!",
JOptionPane.CLOSED_OPTION);
return;
}
Metadado m = tableModelDoc.selecao(index);
BasicDBObject id = new BasicDBObject("metadata.Titulo",
m.getTitulo());
GridFSDBFile fileout = myFS.findOne(id);
JFileChooser salvandoArquivo = new JFileChooser();
String nome = fileout.getFilename();
salvandoArquivo.setSelectedFile(new File(nome));
int resultado = salvandoArquivo.showSaveDialog(this);
if (resultado == JFileChooser.APPROVE_OPTION) {
File salvarArquivoEscolhido = salvandoArquivo.getSelectedFile();
if (salvarArquivoEscolhido.exists() == true) {
int selecionaOpcao = JOptionPane.showConfirmDialog(null,
" O arquivo j existe, deseja sobrescreve-lo? ", null,
JOptionPane.OK_CANCEL_OPTION);
if (selecionaOpcao == JOptionPane.OK_OPTION) {
fileout.writeTo(salvarArquivoEscolhido);
}
} else {
fileout.writeTo(salvarArquivoEscolhido);

JOptionPane.showConfirmDialog(null,
" Arquivo descarregado com sucesso ", null,
JOptionPane.CLOSED_OPTION);

}
// Metodo para limpar a tela de busca
private void limparTela() {
int x = tableModelDoc.getRowCount();
for (int i = 0; i < x; i++) {
tableModelDoc.limparTela();
}
tfTituloDoc.setText("");
}

81

A.2

BuscaDocAdm.java

package aplicacao;
import
import
import
import
import
import
import
import
import
import
import
import
import

com.mongodb.BasicDBObject;
com.mongodb.DB;
com.mongodb.DBCursor;
com.mongodb.Mongo;
com.mongodb.gridfs.GridFS;
com.mongodb.gridfs.GridFSDBFile;
com.mongodb.util.JSON;
com.mongodb.util.JSONParseException;
java.net.UnknownHostException;
java.util.regex.Pattern;
javax.swing.JOptionPane;
javax.swing.JTable;
org.bson.types.ObjectId;

public class BuscaDocAdm extends javax.swing.JFrame {


private DB db;
Mongo mongo;
GridFS myFS;
private String user;
private String pwd;
private TableModelDoc tableModelDoc;
public BuscaDocAdm(DB db, String user, String pwd) {
this.db = db;
this.user = user;
this.pwd = pwd;
initComponents();
//Adicionado para gerar tabela
tableModelDoc = new TableModelDoc();
tableDoc.setModel(tableModelDoc);
tableDoc.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
tableDoc.getColumnModel().getColumn(0).setPreferredWidth(tableDoc.get
Width() / 2);
tableDoc.getColumnModel().getColumn(1).setPreferredWidth(tableDoc.get
Width() / 4);
tableDoc.getColumnModel().getColumn(2).setPreferredWidth(tableDoc.get
Width() / 4);
tableDoc.getColumnModel().getColumn(3).setPreferredWidth(tableDoc.get
Width() / 20);
tableModelDoc.fireTableDataChanged();
conectar(db, user, pwd);
}
/**
* This method is called from within the constructor to initialize the
form.

82
* WARNING: Do NOT modify this code. The content of this method is
always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
// </editor-fold>

private void buttonPesquisarActionPerformed(java.awt.event.ActionEvent


evt) {
// TODO add your handling code here:
limparTela();
String busca = tfBusca.getText();
if (busca.length() > 2) {
String buscaCampo = (String) comboBusca.getSelectedItem();
BasicDBObject query = formataConsulta(buscaCampo, busca);
consultaBanco(query);
} else {
JOptionPane.showConfirmDialog(null,
" Digite uma busca com pelo menos 3 caracteres! ", "Alerta!",
JOptionPane.CLOSED_OPTION);
}
}
private void buttonExcluirActionPerformed(java.awt.event.ActionEvent
evt) {
// TODO add your handling code here:tfIdObjeto
excluir();
}
private void buttonDetalharActionPerformed(java.awt.event.ActionEvent
evt) {
// TODO add your handling code here:
//Codigo para Visualizar detalhes
detalhar();
}
private void jmSairActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
System.exit(0);
}
private void
jmInserirMonografiaActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
NovoDocumento telaNovoDoc = new NovoDocumento(myFS);
telaNovoDoc.setVisible(true);
}
private void tableDocMouseClicked(java.awt.event.MouseEvent evt) {
// TODO add your handling code here:
selecao();
}
{

private void buttonEditarActionPerformed(java.awt.event.ActionEvent evt)

83

// TODO add your handling code here:


editar();

private void tableDocKeyReleased(java.awt.event.KeyEvent evt) {


// TODO add your handling code here:
selecao();
}
private void buttonSairActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
System.exit(0);
}
private void buttonLimparBuscaActionPerformed(java.awt.event.ActionEvent
evt) {
// TODO add your handling code here:
tfBusca.setText("");
limparTela();
}
private void buttonInserirDocActionPerformed(java.awt.event.ActionEvent
evt) {
// TODO add your handling code here:
NovoDocumento telaNovoDoc = new NovoDocumento(myFS);
telaNovoDoc.setVisible(true);
}
private void buttonCancelarActionPerformed(java.awt.event.ActionEvent
evt) {
// TODO add your handling code here:
jdConsultaAvancada.setVisible(false);
}
private void buttonConsultarActionPerformed(java.awt.event.ActionEvent
evt) {
// TODO add your handling code here:
limparTela();
String query = textConsultaAvancada.getText();
if (query.length() > 3) {
try {
BasicDBObject n = (BasicDBObject) JSON.parse(query);
consultaBanco(n);
jdConsultaAvancada.setVisible(false);
} catch (JSONParseException evParseException) {
jdConsultaAvancada.setVisible(false);
}
} else {
jdConsultaAvancada.setVisible(false);
}
}
private void
buttonConsultaAvancadaActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
jdConsultaAvancada.pack();
jdConsultaAvancada.setVisible(true);
}

84
private void
jmConsultaAvancadaActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
jdConsultaAvancada.pack();
jdConsultaAvancada.setVisible(true);
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting
code (optional) ">
//</editor-fold>
/*
* Create and display the form
*/
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new BuscaDocAdm(null, null, null).setVisible(true);
}

});
}
// Variables declaration - do not modify
private javax.swing.JButton buttonCancelar;
private javax.swing.JButton buttonConsultaAvancada;
private javax.swing.JButton buttonConsultar;
private javax.swing.JButton buttonDetalhar;
private javax.swing.JButton buttonEditar;
private javax.swing.JButton buttonExcluir;
private javax.swing.JButton buttonInserirDoc;
private javax.swing.JButton buttonLimparBusca;
private javax.swing.JButton buttonPesquisar;
private javax.swing.JButton buttonSair;
private javax.swing.JComboBox comboBusca;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JMenuBar jMenuBar1;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JDialog jdConsultaAvancada;
private javax.swing.JMenuItem jmConsultaAvancada;
private javax.swing.JMenuItem jmInserirMonografia;
private javax.swing.JMenuItem jmSair;
private javax.swing.JPopupMenu.Separator jsSeparador1;
private javax.swing.JPopupMenu.Separator jsSeparador2;
private javax.swing.JLabel labelConsAvancada;
private javax.swing.JLabel labelTitulo;
private javax.swing.JMenu menuAdm;
private javax.swing.JTable tableDoc;
private javax.swing.JTextArea textConsultaAvancada;
private javax.swing.JTextField tfBusca;
private javax.swing.JTextField tfTituloDoc;
// End of variables declaration

85
/**
* @return the tableDoc
*/
public javax.swing.JTable getTableDoc() {
return tableDoc;
}
/**
* @return the tfTituloDoc
*/
public javax.swing.JTextField getTfTituloDoc() {
return tfTituloDoc;
}
/**
* @param tfTituloDoc the tfTituloDoc to set
*/
public void setTfTituloDoc(javax.swing.JTextField tfTituloDoc) {
this.tfTituloDoc = tfTituloDoc;
}
void conectar(DB db, String user, String pwd) {

try {
mongo = new Mongo("localhost", 27017);
db = mongo.getDB("repositorio");
boolean aut = db.authenticate(user, pwd.toCharArray());
myFS = new GridFS(db);
} catch (UnknownHostException ex) {
ex.printStackTrace();
}

private BasicDBObject formataConsulta(String chave, String busca) {


String exprReg = "^.*" + busca + ".*$";
Pattern valor = Pattern.compile(exprReg, Pattern.CASE_INSENSITIVE);
BasicDBObject query = new BasicDBObject("metadata." + chave, valor);
return query;
}
private void consultaBanco(BasicDBObject query) {
try {
DBCursor cursor = myFS.getFileList(query);
while (cursor.hasNext()) {
BasicDBObject metadados = (BasicDBObject)
cursor.next().get("metadata");
String mTitulo = (String) metadados.get("Titulo");
String mAutor = (String) metadados.get("Autor");
String mOrientador = (String) metadados.get("Orientador");
String mAno = (String) metadados.get("Ano");
Metadado m = new Metadado(mTitulo, mAutor, mOrientador, mAno);
inserirTable(m);
}
} catch (Exception ex) {
System.out.println("Sem resultado...");
}
}

86
private void selecao() {
int index = getTableDoc().getSelectedRow();
if (index == -1) {
return;
}
Metadado m = tableModelDoc.selecao(index);
getTfTituloDoc().setText(m.getTitulo());
}
private void inserirTable(Metadado met) {
if (met != null) {
tableModelDoc.incluir(met);
}
}
private void excluir() {
int index = getTableDoc().getSelectedRow();
if (index == -1) {
JOptionPane.showConfirmDialog(null,
" Nenhum registro selecionado! ", "Alerta!",
JOptionPane.CLOSED_OPTION);
return;
}
Metadado m = tableModelDoc.selecao(index);
String titulo = m.getTitulo();
BasicDBObject id = new BasicDBObject("metadata.Titulo", titulo);
int selecionaOpcao = JOptionPane.showConfirmDialog(null,
" Deseja excluir a seguinte monografia: " + titulo + "?",
"Confirmao de excluso",
JOptionPane.OK_CANCEL_OPTION);
if (selecionaOpcao == JOptionPane.OK_OPTION) {
myFS.remove(id);
tableModelDoc.excluir(index);
JOptionPane.showConfirmDialog(null,
" Excluso efetuada com sucesso ", "Aviso!",
JOptionPane.CLOSED_OPTION);
}

private void limparTela() {


int x = tableModelDoc.getRowCount();
for (int i = 0; i < x; i++) {
tableModelDoc.limparTela();
}
tfTituloDoc.setText("");
}
// metodo responsavel por editar os metadados
private void editar() {
int index = getTableDoc().getSelectedRow();
if (index == -1) {
JOptionPane.showConfirmDialog(null,
" Nenhum registro selecionado! ", "Alerta!",

87
JOptionPane.CLOSED_OPTION);
return;

}
Metadado m = tableModelDoc.selecao(index);
BasicDBObject query = new BasicDBObject("metadata.Titulo",
m.getTitulo());
GridFSDBFile fileout = myFS.findOne(query);
ObjectId id = (ObjectId) fileout.getId();
BasicDBObject metadados = (BasicDBObject) fileout.get("metadata");
String mTitulo = (String) metadados.get("Titulo");
String mAutor = (String) metadados.get("Autor");
String mOrientador = (String) metadados.get("Orientador");
String mTipo = (String) metadados.get("Tipo");
String mAno = (String) metadados.get("Ano");
String mSemestre = (String) metadados.get("Semestre");
String mResumo = (String) metadados.getString("Resumo");
EditarDocumento telaEditarDoc = new EditarDocumento(myFS, id,
mTitulo, mAutor, mOrientador, mTipo, mAno, mSemestre, mResumo);
}

telaEditarDoc.setVisible(true);

// metodo para detalhar um registro


private void detalhar() {
int index = getTableDoc().getSelectedRow();
if (index == -1) {
JOptionPane.showConfirmDialog(null,
" Nenhum registro selecionado! ", "Alerta!",
JOptionPane.CLOSED_OPTION);
return;
}
Metadado m = tableModelDoc.selecao(index);
BasicDBObject query = new BasicDBObject("metadata.Titulo",
m.getTitulo());
GridFSDBFile fileout = myFS.findOne(query);
if (fileout == null) {
JOptionPane.showConfirmDialog(null,
" O registro selecionado foi alterado. preciso refazer a
consulta ", "Alerta!",
JOptionPane.CLOSED_OPTION);
return;
}
ObjectId id = (ObjectId) fileout.getId();
BasicDBObject metadados = (BasicDBObject) fileout.get("metadata");
String mTitulo = (String) metadados.get("Titulo");
String mAutor = (String) metadados.get("Autor");
String mOrientador = (String) metadados.get("Orientador");
String mTipo = (String) metadados.get("Tipo");
String mAno = (String) metadados.get("Ano");
String mSemestre = (String) metadados.get("Semestre");
String mResumo = (String) metadados.getString("Resumo");
VisualizarDetalhes telaVisualizarDoc = new VisualizarDetalhes(id,
mTitulo, mAutor, mOrientador, mTipo, mAno, mSemestre, mResumo);
telaVisualizarDoc.setVisible(true);
}
}

88

A.3

NovoDocumento.java

package aplicacao;
import
import
import
import
import
import
import
import
import
import
import

com.mongodb.BasicDBObject;
com.mongodb.DBCursor;
com.mongodb.gridfs.GridFS;
com.mongodb.gridfs.GridFSInputFile;
java.io.*;
java.math.BigInteger;
java.security.MessageDigest;
java.security.NoSuchAlgorithmException;
java.text.SimpleDateFormat;
java.util.Date;
javax.swing.JOptionPane;

/**
*
* @author ivan
*/
class FiltroArquivosPDF extends javax.swing.filechooser.FileFilter {
@Override
public boolean accept(File file) {
// Allow only directories, or files with ".xml" extension
return file.isDirectory() || file.getAbsolutePath().endsWith(".pdf");
}

@Override
public String getDescription() {
return "Arquivos PDF (*.pdf)";
}

public class NovoDocumento extends javax.swing.JFrame {


GridFS myFS;
/**
* Creates new form NovoDocumento
*/
public NovoDocumento(GridFS myFS) {
this.myFS = myFS;
initComponents();
}
/**
* This method is called from within the constructor to initialize the
form.
* WARNING: Do NOT modify this code. The content of this method is
always
* regenerated by the Form Editor.
*/

89
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
// </editor-fold>

private void buttonInserir1ActionPerformed(java.awt.event.ActionEvent


evt) {
// TODO add your handling code here:
inserir();
}
{

private void buttonLimparActionPerformed(java.awt.event.ActionEvent evt)


// TODO add your handling code here:
limpar();
}

private void botaoBuscarPDFActionPerformed(java.awt.event.ActionEvent


evt) {
// TODO add your handling code here:
fileChooser.setCurrentDirectory(new java.io.File("C:\\"));
fileChooser.getSelectedFile();
fileChooser.setFileFilter(new FiltroArquivosPDF());
fileChooser.setVisible(true);
jFrame1.pack();
jFrame1.setVisible(true);
}
// Acao do botao Abrir
private void fileChooserActionPerformed(java.awt.event.ActionEvent evt)
{

switch (evt.getActionCommand()) {
case "ApproveSelection":
File f = fileChooser.getSelectedFile();
getTfArquivoPdf().setText(f.getAbsolutePath());
jFrame1.dispose();
break;
case "CancelSelection":
jFrame1.dispose();
break;
}

private void buttonCancelarActionPerformed(java.awt.event.ActionEvent


evt) {
// TODO add your handling code here:
dispose();
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting
code (optional) ">

90
//</editor-fold>
/*
* Create and display the form
*/
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new NovoDocumento(null).setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JToggleButton botaoBuscarPDF;
private javax.swing.JButton buttonCancelar;
private javax.swing.JButton buttonInserir1;
private javax.swing.JButton buttonLimpar;
private javax.swing.JComboBox comboAno;
private javax.swing.JComboBox comboSemestre;
private javax.swing.JComboBox comboTipo;
private javax.swing.JFileChooser fileChooser;
private javax.swing.JFrame jFrame1;
private javax.swing.JPanel jPanel1;
private javax.swing.JScrollPane jScrollPane3;
private javax.swing.JLabel labelAno;
private javax.swing.JLabel labelArquivo;
private javax.swing.JLabel labelAutor;
private javax.swing.JLabel labelOrientador;
private javax.swing.JLabel labelResumo;
private javax.swing.JLabel labelSemestre;
private javax.swing.JLabel labelTipo;
private javax.swing.JLabel labelTitulo;
private javax.swing.JTextArea textAreaResumo;
private javax.swing.JTextField tfArquivoPdf;
private javax.swing.JTextField tfAutor;
private javax.swing.JTextField tfOrientador;
private javax.swing.JTextField tfTitulo;
// End of variables declaration
/**
* @return the tfTitulo
*/
public javax.swing.JTextField gettfTitulo() {
return tfTitulo;
}
/**
* @return the tfAutor
*/
public javax.swing.JTextField gettfAutor() {
return tfAutor;
}
/**
* @return the tfOrientador
*/
public javax.swing.JTextField getTfOrientador() {
return tfOrientador;
}

91
/**
* @return the labelTitulo
*/
public javax.swing.JLabel getlabelTitulo() {
return labelTitulo;
}
/**
* @return the comboAno
*/
public javax.swing.JComboBox getComboAno() {
return comboAno;
}
/**
* @return the comboSemestre
*/
public javax.swing.JComboBox getComboSemestre() {
return comboSemestre;
}
/**
* @return the comboTipo
*/
public javax.swing.JComboBox getComboTipo() {
return comboTipo;
}
/**
* @return the tfArquivoPdf
*/
public javax.swing.JTextField getTfArquivoPdf() {
return tfArquivoPdf;
}
/**
* @return the textAreaResumo
*/
public javax.swing.JTextArea getTextAreaResumo() {
return textAreaResumo;
}
/**
* @return the labelNota
*/
public javax.swing.JLabel getLabelNota() {
return labelAno;
}
private void inserir() {
String textTitulo = labelTitulo.getText();
String titulo = tfTitulo.getText();
String textAutor = labelAutor.getText();
String autor = tfAutor.getText();
String textOrientador = labelOrientador.getText();
String orientador = tfOrientador.getText();
String tipoDoc = labelTipo.getText();
String tipo = (String) getComboTipo().getSelectedItem();
String textAno = labelAno.getText();

92
String
String
String
String
String

ano = (String) getComboAno().getSelectedItem();


textSemestre = labelSemestre.getText();
semestre = (String) getComboSemestre().getSelectedItem();
textResumo = labelResumo.getText();
resumo = getTextAreaResumo().getText();

BasicDBObject metadados = new BasicDBObject();


metadados.put(textTitulo, titulo);
metadados.put(textAutor, autor);
metadados.put(textOrientador, orientador);
metadados.put(tipoDoc, tipo);
metadados.put(textAno, ano);
metadados.put(textSemestre, semestre);
metadados.put(textResumo, resumo);
String pathArquivoPdf = getTfArquivoPdf().getText();
if ("".equals(titulo) || "".equals(autor) || "".equals(orientador) ||
"".equals(tipo)
|| "".equals(ano) || "".equals(semestre) ||
"".equals(pathArquivoPdf) || "".equals(resumo)) {
JOptionPane.showConfirmDialog(null,
" Todos os campos devem estar preenchidos! ", "Alerta!",
JOptionPane.CLOSED_OPTION);
} else {
insereDocumento(metadados, pathArquivoPdf);
}
}
// Metodo para inserir o documento na Base de Dados
private void insereDocumento(BasicDBObject metadados, String
pathArquivoPdf) {
File file = new File(pathArquivoPdf);
String md5 = null;
try {
md5 = geraHash(file);
} catch (NoSuchAlgorithmException | FileNotFoundException e1) {
}
boolean existeArquivo = verificaExistePdf(md5, myFS);
if (!existeArquivo) {
try {
GridFSInputFile inputFile = myFS.createFile(file);
inputFile.setMetaData(metadados);
inputFile.save();
JOptionPane.showConfirmDialog(null,
" Nova monografia guardada com sucesso! ", null,
JOptionPane.CLOSED_OPTION);
dispose();
} catch (IOException ex) {
}
} else {
JOptionPane.showConfirmDialog(null,
" O arquivo PDF j existe na base de dados! ", null,
JOptionPane.CLOSED_OPTION);

93
}
}
// Gera a lista dos anos no combobox
public String[] buscarAnos() {
String dados[] = null;
Date hoje = new Date();
String formato = "yyyy";
SimpleDateFormat formatter = new SimpleDateFormat(formato);
int anoatual = Integer.parseInt(formatter.format(hoje));
dados = new String[anoatual - 1898];
dados[0] = "";
for (int i = 1; anoatual >= 1900; i++) {
dados[i] = String.valueOf(anoatual);
anoatual--;
}
return dados;
}
// Verifica se existe a Hash md5 no gridfs
private boolean verificaExistePdf(String md5, GridFS myFS) {
boolean existe = false;
BasicDBObject query = new BasicDBObject("md5", md5);
DBCursor cursor = myFS.getFileList(query);
if (cursor.hasNext()) {
return true;
} else {
return false;
}
}
//Gera a hash md5 do arquivo a ser inserido
public String geraHash (File f) throws NoSuchAlgorithmException,
FileNotFoundException {
MessageDigest digest = MessageDigest.getInstance("MD5");
InputStream is = new FileInputStream(f);
byte[] buffer = new byte[8192];
int read = 0;
String output = null;
try {
while ((read = is.read(buffer)) > 0) {
digest.update(buffer, 0, read);
}
byte[] md5sum = digest.digest();
BigInteger bigInt = new BigInteger(1, md5sum);
output = bigInt.toString(16);
} catch (IOException e) {
throw new RuntimeException("No foi possivel processar o
arquivo.", e);
} finally {
try {
is.close();
} catch (IOException e) {
throw new RuntimeException("No foi possivel fechar o arquivo",
e);
}
}

94
return output;
}

A.4

// Limpa todos os campos


private void limpar() {
gettfTitulo().setText("");
gettfAutor().setText("");
getTfOrientador().setText("");
getComboAno().setSelectedIndex(-1);
getComboSemestre().setSelectedIndex(0);
getTextAreaResumo().setText("");
}

EditarDocumento.java

package aplicacao;
import com.mongodb.BasicDBObject;
import com.mongodb.gridfs.GridFS;
import com.mongodb.gridfs.GridFSDBFile;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JOptionPane;
import org.bson.types.ObjectId;
public class EditarDocumento extends javax.swing.JFrame {
GridFS myFS;
ObjectId id;
String titulo;
String autor;
String orientador;
String tipo;
String ano;
String semestre;
String resumo;
public EditarDocumento(GridFS myFS, ObjectId id, String titulo, String
autor, String orientador,
String tipo, String ano, String semestre, String resumo) {
this.myFS = myFS;
this.id = id;
this.titulo = titulo;
this.autor = autor;
this.orientador = orientador;
this.tipo = tipo;
this.ano = ano;
this.semestre = semestre;

95

this.resumo = resumo;
initComponents();

/**
* This method is called from within the constructor to initialize the
form.
* WARNING: Do NOT modify this code. The content of this method is
always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
}// </editor-fold>

private void buttonSalvarActionPerformed(java.awt.event.ActionEvent evt)


// TODO add your handling code here
editar();
}

private void buttonCancelarActionPerformed(java.awt.event.ActionEvent


evt) {
// TODO add your handling code here:
dispose();
}
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting
code (optional) ">
//</editor-fold>
/*
* Create and display the form
*/
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new EditarDocumento(null, null, null, null, null, null, null,
null, null).setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton buttonCancelar;
private javax.swing.JButton buttonSalvar;
private javax.swing.JComboBox comboAno;
private javax.swing.JComboBox comboSemestre;
private javax.swing.JComboBox comboTipo;
private javax.swing.JPanel jPanel1;
private javax.swing.JScrollPane jScrollPane3;
private javax.swing.JLabel labelAno;
private javax.swing.JLabel labelAutor;

96
private javax.swing.JLabel labelOrientador;
private javax.swing.JLabel labelResumo;
private javax.swing.JLabel labelSemestre;
private javax.swing.JLabel labelTipo;
private javax.swing.JLabel labelTitulo;
private javax.swing.JTextArea textAreaResumo;
private javax.swing.JTextField tfAutor;
private javax.swing.JTextField tfOrientador;
private javax.swing.JTextField tfTitulo;
// End of variables declaration
// Captura os metadados e chama o metodo para guardar na Base de Dados
private void editar() {
String textTitulo = labelTitulo.getText();
titulo = tfTitulo.getText();
String textAutor = labelAutor.getText();
autor = tfAutor.getText();
String textOrientador = labelOrientador.getText();
orientador = tfOrientador.getText();
String tipoDoc = labelTipo.getText();
tipo = (String) comboTipo.getSelectedItem();
String textAno = labelAno.getText();
ano = (String) comboAno.getSelectedItem();
String textSemestre = labelSemestre.getText();
semestre = (String) comboSemestre.getSelectedItem();
String textResumo = labelResumo.getText();
resumo = textAreaResumo.getText();
//resumo = getTextAreaResumo().getText();
BasicDBObject metadados = new BasicDBObject();
metadados.put(textAutor, autor);
metadados.put(textTitulo, titulo);
metadados.put(textOrientador, orientador);
metadados.put(tipoDoc, tipo);
metadados.put(textAno, ano);
metadados.put(textSemestre, semestre);
metadados.put(textResumo, resumo);
if ("".equals(titulo) || "".equals(autor) || "".equals(orientador) ||
"".equals(tipo)
|| "".equals(ano) || "".equals(semestre) || "".equals(resumo)) {
JOptionPane.showConfirmDialog(null,
" Todos os campos devem estar preenchidos! ", "Alerta!",
JOptionPane.CLOSED_OPTION);
} else {
editarMetadados(id, metadados);
}
}
// Metodo para gerar os anos no combobox
public String[] buscarAnos() {
String dados[] = null;
Date hoje = new Date();
String formato = "yyyy";
SimpleDateFormat formatter = new SimpleDateFormat(formato);
int anoatual = Integer.parseInt(formatter.format(hoje));
dados = new String[anoatual - 1898];

97
dados[0] = "";
for (int i = 1; anoatual >= 1900; i++) {
dados[i] = String.valueOf(anoatual);
anoatual--;
}
return dados;
}
// Editar os metadados na Base de Dados
private void editarMetadados (ObjectId id, BasicDBObject metadados) {

GridFSDBFile file = myFS.findOne(id);


file.setMetaData(metadados);
file.save();
dispose();

A.5

VisualizarDetalhes.java

package aplicacao;
import org.bson.types.ObjectId;
public class VisualizarDetalhes extends javax.swing.JFrame {
ObjectId id;
String titulo;
String autor;
String orientador;
String tipo;
String ano;
String semestre;
String resumo;
public VisualizarDetalhes (ObjectId id, String titulo, String autor,
String orientador, String tipo, String ano, String semestre,
String resumo) {
this.id = id;
this.titulo = titulo;
this.autor = autor;
this.orientador = orientador;
this.tipo = tipo;
this.ano = ano;
this.semestre = semestre;
this.resumo = resumo;
initComponents();
}

98
/**
* This method is called from within the constructor to initialize the
form.
* WARNING: Do NOT modify this code. The content of this method is
always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
// </editor-fold>

private void buttonFecharActionPerformed(java.awt.event.ActionEvent evt)


// TODO add your handling code here:
dispose();
}
public static void main(String args[]) {

//<editor-fold defaultstate="collapsed" desc=" Look and feel setting


code (optional) ">
//</editor-fold>
/*
* Create and display the form
*/
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new VisualizarDetalhes(null, null, null, null, null,
null, null, null).setVisible(true);
}

});
}
// Variables declaration - do not modify
private javax.swing.JButton buttonFechar;
private javax.swing.JPanel jPanel1;
private javax.swing.JScrollPane jScrollPane3;
private javax.swing.JLabel labelAno;
private javax.swing.JLabel labelAutor;
private javax.swing.JLabel labelOrientador;
private javax.swing.JLabel labelResumo;
private javax.swing.JLabel labelSemestre;
private javax.swing.JLabel labelTipo;
private javax.swing.JLabel labelTitulo;
private javax.swing.JTextArea textAreaResumo;
private javax.swing.JTextField tfAno;
private javax.swing.JTextField tfAutor;
private javax.swing.JTextField tfOrientador;
private javax.swing.JTextField tfSemestre;
private javax.swing.JTextField tfTipo;
private javax.swing.JTextField tfTitulo;
// End of variables declaration
}

99
A.6

TableModelDocjava

package aplicacao;
import java.util.ArrayList;
import javax.swing.table.AbstractTableModel;
public class TableModelDoc extends AbstractTableModel {
private static final String[] columnNames = {"Titulo", "Autor",
"Orientador", "Ano"};
private ArrayList<Metadado> docs;
public TableModelDoc() {
docs = new ArrayList<>();
}
public void incluir(Metadado l) {
docs.add(l);
fireTableRowsInserted(docs.size() - 1, docs.size() - 1);
}
public void excluir(int index) {
docs.remove(index);
fireTableRowsDeleted(1, getRowCount());
}
public void limparTela() {
docs.remove(0);
fireTableRowsDeleted(1, getRowCount());
}
public Metadado selecao(int index) {
return docs.get(index);
}

@Override
public int getRowCount() {
return docs.size();
}
@Override
public String getColumnName(int columnIndex) {
return columnNames[columnIndex];
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
switch (columnIndex) {
case 0:
return docs.get(rowIndex).getTitulo();
case 1:
return docs.get(rowIndex).getAutor();
case 2:
return docs.get(rowIndex).getOrientador();
case 3:
return docs.get(rowIndex).getAno();
}
return null;
}

100

A.7

Metadado.java

package aplicacao;
public class Metadado {
private
private
private
private

String
String
String
String

titulo;
autor;
orientador;
ano;

public Metadado() {
}
public Metadado(String titulo, String autor, String orientador, String
ano) {
this.titulo = titulo;
this.autor = autor;
this.orientador = orientador;
this.ano = ano;
}
public String getTitulo() {
return titulo;
}
public void setTitulo(String titulo) {
this.titulo = titulo;
}
public String getAutor() {
return autor;
}
public void setAutor(String autor) {
this.autor = autor;
}
public String getOrientador() {
return orientador;
}
public void setOrientador(String orientador) {
this.orientador = orientador;
}
public String getAno() {
return ano;
}
public void setAno(String ano) {
this.ano = ano;
}
}

Você também pode gostar