Created
March 16, 2012 18:20
-
-
Save fredericorecsky/2051627 to your computer and use it in GitHub Desktop.
perl e mongoDB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Perl e MongoDB | |
Introdução | |
Há algum tempo atrás começou uma onda de NOSQL e eu a principio só me mantive | |
observando a distancia. A questão é que como toda coisa nova acaba sendo | |
sobreutilizada ou utilizada em funções erradas. | |
No caso existem na internet diversos textos sobre o Mongo, usos e etc. Nesse | |
artigo vou abordar um uso bem simples mas que por conta das caracteristicas do | |
mongodb o tornaram quase que uma luva. | |
Essas caracteristicas são schema free e documented oriented. No caso estou | |
desenvolvendo um leitor de rss/atom/xml e que eu preciso escrever pequenos | |
"pontos de dados" e que roda em cluster. Também ele tem diversos crawlers | |
internos dos quais cada um tem sua configuração. | |
É possivel fazer utilizando mysql ou postgres ou qualquer outro, mas a | |
simplicidade de se erguer um servidor mongo sem esquema definido e que | |
possibilita salvar documentos json direto facilita muito o desenvolvimento. | |
Especialmente para empresas que tem seus negocios apenas baseado em aplicações | |
internet que não tem de fato a arquitetura final definida. | |
Requisitos | |
Claro que Perl, uma instancia de MongoDB e o modulo do MongoDB do cpan. | |
* http://www.mongodb.org/ | |
* http://search.cpan.org/~kristina/MongoDB-0.45/lib/MongoDB.pm | |
Para começar estou assumindo que o programa perl está na mesma maquina em que | |
o mongo está rodando, mas é trivial configurar para um servidor diferente. | |
Basicão | |
<code> | |
use strict; | |
use warnings; | |
use MongoDB; | |
my $connection = MongoDB::Connection->new( host => 'localhost', port => 27017); | |
my $database = $connection->get_database('sppm'); | |
my $collection = $database->get_collection('equinocio'); | |
my $data = $collection->find_one({ type => "artigo" }); | |
</code> | |
Além do header classico, temos a declaração do modulo do MongoDB e as strings de | |
conexão e de escolha de database e collection. Collection é um nome bonito para | |
o que seria uma tabela num banco de dados classico. | |
Note que se o database não existir será autovivificado, assim como a collection. | |
Se você rodar esse exemplo $data estara vazio por motivos obvios :). | |
Vamos assumir que esse script roda eventualmente pegando a tabela de artigos da | |
sppm e avisa se há novos. A Tabela de artigos tem esse schema: | |
artigo, data, link | |
Obvio que eu não gostaria de varrer todos os registros toda vez, assim como que | |
por algum motivo valido eu não quero ou não posso alterar o banco de dados. | |
Então eu gostaria que esse script, salvasse a data em que ele leu da ultima vez | |
a tabela para que na proxima continuasse de onde parou. | |
Então depois de varrer a tabela eu gostaria de salvar somente o ultimo timestamp | |
em que o script o fez. | |
<code> | |
my $timestamp_id = $collection->insert({ last_verified => '1999/12/31 23:59:59' }); | |
</code> | |
Isso insere o valor "last_verified" na collection equinocio e retorna uma id, no | |
caso, "4f6367450be985cd5c000000". Note que ao inserir uma nova chave é gerado | |
um novo id. Esse id é o id do conjunto de chave valor. E voce pode ter duas | |
chaves valores iguais. | |
Se executar duas vezes e for ao console do mongo db: | |
<console> | |
> db.equinocio.find() | |
{ "_id" : ObjectId("4f6367450be985cd5c000000"), "last_verified" : "1999/12/31 23:59:59" } | |
{ "_id" : ObjectId("4f6368b7279b784b6b000000"), "last_verified" : "1999/12/31 23:59:59" } | |
</console> | |
Temos duas entradas para "last_verified". | |
Collections | |
No nosso caso queremos apenas salvar a data que nós varremos o banco de dados | |
pela ultima vez. Então vamos apagar as entradas e vamos criar só uma. Quando | |
o script for executado ele tentara primeiro recuperar last_verified e depois | |
escrevera o resultado. | |
A classe que manipula Collections no Mongo é MongoDB::Collection: | |
http://search.cpan.org/~kristina/MongoDB-0.45/lib/MongoDB/Collection.pm | |
Vamos apagar todos os last_verified para começar de novo, primeiro vamos | |
achar todos objetos "last_verified". | |
<code> | |
my $data = $collection->find({ last_verified => '1999/12/31 23:59:59' } ); | |
</code> | |
$data é um objeto MongoDB::Cursor, um iterador para varios items numa lista de | |
resultados. Como eu executei varias vezes temos uma coleção de timestamps | |
repetidos... | |
jeferson@ps80344:~/Reader/bin$ perl mongo.pl | |
$VAR1 = { | |
'_id' => bless( { | |
'value' => '4f6367450be985cd5c000000' | |
}, 'MongoDB::OID' ), | |
'last_verified' => '1999/12/31 23:59:59' | |
}; | |
$VAR1 = { | |
'_id' => bless( { | |
'value' => '4f6368b7279b784b6b000000' | |
}, 'MongoDB::OID' ), | |
'last_verified' => '1999/12/31 23:59:59' | |
}; | |
$VAR1 = { | |
'_id' => bless( { | |
'value' => '4f636a8cd8947c5c7e000000' | |
}, 'MongoDB::OID' ), | |
'last_verified' => '1999/12/31 23:59:59' | |
}; | |
Vamos apaga-los e manter somente um. A classe Cursor permite que se apague (drop) | |
todo o collection de uma vez: | |
$collection->drop; | |
Mas isso é muito simples, vamos apagar todos menos um. De quebra aprendemos sobre | |
o OID. | |
OID | |
Cada documento armazenado contem um id unico, Object Id, ( vulgo OID ). Ele é | |
um hash key para cada set de key values e é unico. Para apagar vamos iterar sobre | |
o resultado ( Cursor ) e apagar todos menos um. Para apagar devemos passar uma | |
query para o metodo remove. Isso significa que se para apagar sub-sets de dados | |
semelhantes temos que recolher os ids e apaga-los individualmente. | |
Então temos: | |
<code> | |
my $data = $collection->find(); | |
my @all_copies = $data->all; | |
pop @all_copies; | |
for my $object ( @all_copies ){ | |
$collection->remove( { _id => $object->{ _id } } ) ; | |
} | |
</code> | |
Primeiro recuperamos todos os registros com um find() sem parametros. Salvamos | |
todos os OID num array e removemos um com pop. Esse removido sera salvo. Depois | |
iteramos os objetos e os removemos. | |
$object->{ _id } = Mongo::OID dentro do resultado do Cursor. | |
O cursor retorna o OID mais um hash com os keys values. Não é muito sabio usar | |
'_id' como chave quando estiver utilizando-o. | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment