Escolar Documentos
Profissional Documentos
Cultura Documentos
Revisão Da Literatura
Revisão Da Literatura
CENTRO DE TECNOLOGIA
CURSO DE CINCIA DA COMPUTAO
TRABALHO DE GRADUAO
por
elaborado por
Ivan Isaas Friess
como requisito parcial para obteno do grau de
Bacharel em Cincia da Computao
COMISSO EXAMINADORA:
AGRADECIMENTOS
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.
ABSTRACT
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.
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
LISTA DE APNDICES
ACID
AGPL
API
ASF
BASE
BSON
Binary JSON
CQL
HDFS
HTTP
JDK
JSON
NOSQL
REST
SGBD
SGBDR
SQL
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
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:
Desenvolvimento da aplicao;
Testes da aplicao;
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).
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.
19
Couchbase, RavenDB, SimpleDB, etc. (FindTheBest, 2012).
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.
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.
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.
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).
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.
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.
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.
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
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.
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).
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.
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).
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
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).
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
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.
acesso
pode
ser
feito
pelo
navegador
atravs
do
endereo
42
Ano Desenvol- Sistema Licena
vedor
Operacional
2009 Salvatore
Sanfilippo
Redis
2010 Basho
Tecnologies
Riak
HBase
2005 Damien
Katz (ex
IBM).
Mantido por
CouchDB
ASF
2007 10gen
MongoDB
Neo4j
2007 Neo
Technology
Linux,
BSD
Mac OS e
Solaris
Arquitetura
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
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:
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.
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.
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.
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.
50
51
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.
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.
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.
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.
56
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.
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.
59
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.
61
anteriormente neste trabalho. Para entender melhor, pode-se visualizar na Figura 4.13 como
fica definido para o arquivo que estamos incluindo.
62
as
consultas
usaro,
na
maioria
das
vezes,
sintaxe
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
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
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.
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
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.
69
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
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.
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
D.
CouchDb
Architecture.
Disponvel
em
MongoDB
Docs.
Disponvel
em
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
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>
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();
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;
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>
83
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();
}
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);
}
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);
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)";
}
89
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
// </editor-fold>
switch (evt.getActionCommand()) {
case "ApproveSelection":
File f = fileChooser.getSelectedFile();
getTfArquivoPdf().setText(f.getAbsolutePath());
jFrame1.dispose();
break;
case "CancelSelection":
jFrame1.dispose();
break;
}
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
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
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>
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) {
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>
});
}
// 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;
}
}