Mostrando postagens com marcador ECMA. Mostrar todas as postagens
Mostrando postagens com marcador ECMA. Mostrar todas as postagens

sábado, 27 de fevereiro de 2010

MongoDB

Logo Há atualmente na Computação uma onda de adoção de bancos de dados não-relacionais, comumente chamados NoSQL.

O foco principal dos bancos NoSQL atuais é a orientação a documentos, uma variação hash da orientação a objetos e alternativa aos RDBMSs, que dominaram a orientação dos gerenciadores de banco de dados por décadas.

O principal banco NoSQL é o CouchDB, DBMS do Projeto Apache baseado em Erlang, porém há uma alternativa bem mais simples e aparentemente tão poderosa quanto: MongoDB.

MongoDB combina os melhores funcionalidades de orientação a documentos, hashes e RDBMSs. É um banco de dados orientado a documentos, escalável, livre de esquema, de alto desempenho e código aberto escrito em C++.

Este artigo dá continuidade ao artigo nas Reflexões de Monte Gasppa e Giulia C. sobre a instalação do MongoDB. Aqui você poderá ver um pouquinho do uso de um banco de dados orientado a documentos.

Este artigo é baseado na documentação oficial e entende que você instalou o MongoDB segundo descrito nas Reflexões de Monte Gasppa e Giulia C..

Conexão na base de dados


Para conectar na base basta usar o comando mongo:
bash$ mongo
MongoDB shell version: 1.2.2
url: test
connecting to: test
type "help" for help
>


Caso você tenha configurado uma porta alternativa em /srv/mongodb/etc/mongodb.conf, você pode especificar isso na linha de comando do cliente:
bash$ mongo --port 27018


Você também pode se conectar a um servidor remoto, caso ele esteja habilitado para conexão externa, usando a flag --host.

Para escolher qual base de dados usar, o comando é use:
> use mydb


Autorização


Você pode se autorizar na linha de comando com as opções -u (usuário) e -p (senha), ou já do prompt do interpretador:
> use admin
> db.auth('admin', 'ra35EG/dz');


Comandos básicos


A linguagem de interação com MongoDB é Javascript, mas há alguns comandos úteis no interpretador.

Para listar comandos úteis:
> help


Listar recursos uteis da base atual:
> db.help();


Listar recursos uteis de uma coleção (levemente equivalente a tabela de um banco relacional), no exemplo foo:
> db.foo.help();


Para listar as bases instaladas:
> show dbs


Para listar as coleções da base atual:
> show collections


Listar usuários da base atual:
> show users


Criar usuário na base atual:
> db.addUser('admin', 'ra35EG/dz');


Autenticar-se:
> db.auth('admin', 'ra35EG/dz');


Listar o conteúdo de uma coleção:
> db.foo.find();


Apagar uma coleção:
> db.foo.drop();


Apagar a base de dados atual:
> db.dropDatabase();


Armazenamento de dados


Repare que o MongoDB é livre de esquema, portanto uma coleção pode conter estruturas de dados radicalmente diferentes, sempre no formato JSON.

Por exemplo, vamos inserir dois dados distintos na coleção foo da base mydb:
> use mydb
> var j = { name: 'mongo' };
> var t = { x: 3 };
> db.foo.save(j);
> db.foo.save(t);
> db.foo.find();
{ "_id" : ObjectId("4b8949d9cd50237b8573833b"), "name" : "mongo" }
{ "_id" : ObjectId("4b8949dbcd50237b8573833c"), "x" : 3 }


Você não precisa predefinir a coleção, que é criada automaticamente no salvamento da primeira estrutura. O campo _id é criado automaticamente e é a chave primária.

Para apagar o objeto j:
> j = db.foo.findOne({ name: 'mongo' });
> db.foo.remove(j);


Para apagar todos os objetos basta remover a coleção:
> db.foo.drop();


Vamos usar um pouco mais de lógica:
> for (var i=0; i<100; ++i) db.foo.save({ x: i, y: i*i });


Esse loop cria cem registros, com x variando de zero a noventa e nove e y igual a seu quadrado:
> db.foo.find();
{ "_id" : ObjectId("4b894c05cd50237b8573833e"), "x" : 0, "y" : 0 }
{ "_id" : ObjectId("4b894c05cd50237b8573833f"), "x" : 1, "y" : 1 }
{ "_id" : ObjectId("4b894c05cd50237b85738340"), "x" : 2, "y" : 4 }
{ "_id" : ObjectId("4b894c05cd50237b85738341"), "x" : 3, "y" : 9 }
{ "_id" : ObjectId("4b894c05cd50237b85738342"), "x" : 4, "y" : 16 }
{ "_id" : ObjectId("4b894c05cd50237b85738343"), "x" : 5, "y" : 25 }
{ "_id" : ObjectId("4b894c05cd50237b85738344"), "x" : 6, "y" : 36 }
{ "_id" : ObjectId("4b894c05cd50237b85738345"), "x" : 7, "y" : 49 }
{ "_id" : ObjectId("4b894c05cd50237b85738346"), "x" : 8, "y" : 64 }
{ "_id" : ObjectId("4b894c05cd50237b85738347"), "x" : 9, "y" : 81 }
{ "_id" : ObjectId("4b894c05cd50237b85738348"), "x" : 10, "y" : 100 }
{ "_id" : ObjectId("4b894c05cd50237b85738349"), "x" : 11, "y" : 121 }
{ "_id" : ObjectId("4b894c05cd50237b8573834a"), "x" : 12, "y" : 144 }
{ "_id" : ObjectId("4b894c05cd50237b8573834b"), "x" : 13, "y" : 169 }
{ "_id" : ObjectId("4b894c05cd50237b8573834c"), "x" : 14, "y" : 196 }
{ "_id" : ObjectId("4b894c05cd50237b8573834d"), "x" : 15, "y" : 225 }
{ "_id" : ObjectId("4b894c05cd50237b8573834e"), "x" : 16, "y" : 256 }
{ "_id" : ObjectId("4b894c05cd50237b8573834f"), "x" : 17, "y" : 289 }
{ "_id" : ObjectId("4b894c05cd50237b85738350"), "x" : 18, "y" : 324 }
{ "_id" : ObjectId("4b894c05cd50237b85738351"), "x" : 19, "y" : 361 }
has more


Consultas (queries)


É possível fazer consultas simples ou bem complexas assim como em modelos relacionais usando MongoDB.

Vamos obter uma contagem de objetos:
> db.foo.find().count();
100


Só os cinco primeiros objetos:
> db.foo.find().limit(5);
{ "_id" : ObjectId("4b894c05cd50237b8573833e"), "x" : 0, "y" : 0 }
{ "_id" : ObjectId("4b894c05cd50237b8573833f"), "x" : 1, "y" : 1 }
{ "_id" : ObjectId("4b894c05cd50237b85738340"), "x" : 2, "y" : 4 }
{ "_id" : ObjectId("4b894c05cd50237b85738341"), "x" : 3, "y" : 9 }


Agora os cinco seguintes:
> db.foo.find().skip(5).limit(5);
{ "_id" : ObjectId("4b894c05cd50237b85738343"), "x" : 5, "y" : 25 }
{ "_id" : ObjectId("4b894c05cd50237b85738344"), "x" : 6, "y" : 36 }
{ "_id" : ObjectId("4b894c05cd50237b85738345"), "x" : 7, "y" : 49 }
{ "_id" : ObjectId("4b894c05cd50237b85738346"), "x" : 8, "y" : 64 }
{ "_id" : ObjectId("4b894c05cd50237b85738347"), "x" : 9, "y" : 81 }


Para obter o elemento com valor de x vinte e quatro:
> var e = db.foo.findOne({ x: 24 });
> print(e.y);
576
> print(tojson(e));
{ "_id" : ObjectId("4b894c05cd50237b85738356"), "x" : 24, "y" : 576 }


Consultas avançadas


Vamos complicar um pouco…

Para obter todos os registros com x maior que cinquenta:
> db.foo.find('this.x > 50');
{ "_id" : ObjectId("4b894c05cd50237b85738371"), "x" : 51, "y" : 2601 }
{ "_id" : ObjectId("4b894c05cd50237b85738372"), "x" : 52, "y" : 2704 }
{ "_id" : ObjectId("4b894c05cd50237b85738373"), "x" : 53, "y" : 2809 }
{ "_id" : ObjectId("4b894c05cd50237b85738374"), "x" : 54, "y" : 2916 }
{ "_id" : ObjectId("4b894c05cd50237b85738375"), "x" : 55, "y" : 3025 }
{ "_id" : ObjectId("4b894c05cd50237b85738376"), "x" : 56, "y" : 3136 }
{ "_id" : ObjectId("4b894c05cd50237b85738377"), "x" : 57, "y" : 3249 }
{ "_id" : ObjectId("4b894c05cd50237b85738378"), "x" : 58, "y" : 3364 }
{ "_id" : ObjectId("4b894c05cd50237b85738379"), "x" : 59, "y" : 3481 }
{ "_id" : ObjectId("4b894c05cd50237b8573837a"), "x" : 60, "y" : 3600 }
{ "_id" : ObjectId("4b894c05cd50237b8573837b"), "x" : 61, "y" : 3721 }
{ "_id" : ObjectId("4b894c05cd50237b8573837c"), "x" : 62, "y" : 3844 }
{ "_id" : ObjectId("4b894c05cd50237b8573837d"), "x" : 63, "y" : 3969 }
{ "_id" : ObjectId("4b894c05cd50237b8573837e"), "x" : 64, "y" : 4096 }
{ "_id" : ObjectId("4b894c05cd50237b8573837f"), "x" : 65, "y" : 4225 }
{ "_id" : ObjectId("4b894c05cd50237b85738380"), "x" : 66, "y" : 4356 }
{ "_id" : ObjectId("4b894c05cd50237b85738381"), "x" : 67, "y" : 4489 }
{ "_id" : ObjectId("4b894c05cd50237b85738382"), "x" : 68, "y" : 4624 }
{ "_id" : ObjectId("4b894c05cd50237b85738383"), "x" : 69, "y" : 4761 }
{ "_id" : ObjectId("4b894c05cd50237b85738384"), "x" : 70, "y" : 4900 }
has more


Outra opção é usar o operador condicional $gt:
> db.foo.find({ x: { $gt: 50 } });


Da mesma forma outros operadores. Por exemplo, todos os elementos com x entre vinte e três e vinte e seis, inclusive:
> db.foo.find('23 <= this.x && this.x <= 26');


Ou:
> db.foo.find({ x: { $gte: 23, $lte: 26 } });


Os principais operadores são:
  • $lt – menor que
  • $gt – maior que
  • $lte – menor ou igual a
  • $gte – maior ou igual a
  • $ne – diferente de
  • $in – está em (recebe uma lista)
  • $nin – não está em
  • $mod – resto igual a (recebe uma lista onde o primeiro valor é o divisor e o segundo o resto)
  • $exists – contém ou não o atributo
  • $not – negação de uma condição


Ordenação


A ordenação é feita usando o método sort. Por exemplo, para ordenar de modo descrescente pelo atributo y:
> db.foo.find().sort({ y: -1 });


Expressões regulares

Quando há campos com valor string, é possível usar expressões regulares:
> db.foo.find({ name: /^mon.o$/i });


Índices

Quando você faz muitas consultas baseadas em um determinado atributo, é interessante criar um índice para ele. Por exemplo, se quisermos criar um índice para nosso atributo x:
> db.foo.ensureIndex({ x: 1 });


Obs.¹: o atributo _id possui índice por padrão.

Obs.²: é possível criar índices compostos.

Agregação


Não vou entrar nesse mérito, mas é possível criar agregações, como GROUP_BY de SQL. Para tanto veja a documentação oficial.

Módulos de conexão com linguagens de programação


Há módulos para várias linguagens, que podem ser encontrados na lista de APIs.

O módulo que pude e me fascinou foi para Python. Sua instalação usando easy_install foi muito simples:
bash$ sudo easy_install -U pymongo


E seu uso extremamente fácil devido à similiaridade entre dicionários de Python e JSON. A única reclamação que faço é o fato do método db.auth() do MongoDB ter sido traduzido como db.authenticate() em Python, o que me fez perder alguns segundos tentando entender por que não funcionava.

**


Espero que este artigo seja mais do que útil e incite o uso dessa intrigante ferramenta.

[]’s
Cacilhas, La Batalema

sábado, 8 de dezembro de 2007

Prettify no Kodumaro

Gente,

Acrescentei Prettify ao Kodumaro.

Prettify é um recurso ECMAScript/CSS para syntax highlighting de códigos em C/C++, Java, Python, Bash, SQL, HTML, XML, CSS, JavaScript e Makefile. Também trabalha bem com Ruby, AWK e Perl.

Não funciona com Smalltalk ou Lisp.

A linguagem é detectada automaticamente.

Para usar Prettify, basta incluir o framework:
<script src="http://vps.jsloader.com/assets/jsloader.js"></script>
<script><!--
JSLoader.load("ria", "prettify", "1.0");
//--></script>


Então no body:
<body onLoad="prettyPrint();">


Feito isso, basta registrar a classe de pre ou code como prettyprint:
<pre><code class="prettyprint">
...
</code></pre>


[]'s
Cacilhas La Batalema