A melhor maneira de trabalhar com o MongoDB e o Python é utilizar a biblioteca PyMongo. No post Conexão do R com bancos de dados - MongoDB mostramos como conectar o R ao MongoDB. Hoje, faremos o mesmo com o Python.
O PyMongo pode ser facilmente instalado via easy_install, via Python Package Index (http://pypi.python.org/pypi/setuptools):
easy_install pymongo
Searching for pymongo
Reading http://pypi.python.org/simple/pymongo/
Reading http://github.com/mongodb/mongo-python-driver
Best match: pymongo 2.7
Downloading ...
Processing pymongo-2.7-py2.6-macosx-10.6-x86_64.egg
Moving ...
Adding pymongo 2.7 to easy-install.pth file
Installed ...
Processing dependencies for pymongo
Finished processing dependencies for pymongo
Após a instalação, importamos o módulo e valos utilizar a classe Connection para fazer a conexão com o MongoDB. Vamos atribuir à variável db a conexão feita com o banco testePyMongo.
Existe uma diferença de sintaxe do PyMongo em relação ao shell do MongoDB. O primeiro utiliza o padrão underscore_naming, enquanto o shell utilizada a padronização camelCase. Ou seja, no shell faríamos db.collection.findOne(), enquanto no PyMongo o mesmo código teria a sintaxe db.collection.find_One(). Como exemplo, insira o documento {"a" : [1, 2, 3]} em nossa collection e execute o find_One.
from pymongo import Connection
db = Connection().testePyMongo
Existe uma diferença de sintaxe do PyMongo em relação ao shell do MongoDB. O primeiro utiliza o padrão underscore_naming, enquanto o shell utilizada a padronização camelCase. Ou seja, no shell faríamos db.collection.findOne(), enquanto no PyMongo o mesmo código teria a sintaxe db.collection.find_One(). Como exemplo, insira o documento {"a" : [1, 2, 3]} em nossa collection e execute o find_One.
db.teste.insert({"a": [1, 2, 3]})
db.teste.find_one()
Para nossa aplicação, vamos trabalhar com os dados fictícios de visitas à páginas de um site. Vamos inserir os seguintes documentos em nossa base, em uma collection nomeada de hourly.
Temos a informação do dia e hora e da quantidade de visitas em cada página. Suponha que os dados são coletados a cada hora. Para as visitas totais ao site temos uma collection separada, chamada de hourly_totals com as informações abaixo.
Vamos agora criar a função track que, toda vez que o site receber uma visita, a hora será armazena e o número de views será incrementado em uma unidade. Nossa collection aqui é a hourly_totals.
{ "hour" : "Tue Jun 15 2010 9:00:00 GMT-0400 (EDT)", "url" : "/foo", "views" : 5 }
{ "hour" : "Tue Jun 15 2010 9:00:00 GMT-0400 (EDT)", "url" : "/bar", "views" : 5 }
{ "hour" : "Tue Jun 15 2010 10:00:00 GMT-0400 (EDT)", "url" : "/", "views" : 12 }
{ "hour" : "Tue Jun 15 2010 10:00:00 GMT-0400 (EDT)", "url" : "/bar", "views" : 3 }
{ "hour" : "Tue Jun 15 2010 10:00:00 GMT-0400 (EDT)", "url" : "/foo", "views" : 10 }
{ "hour" : "Tue Jun 15 2010 11:00:00 GMT-0400 (EDT)", "url" : "/foo", "views" : 21 }
{ "hour" : "Tue Jun 15 2010 11:00:00 GMT-0400 (EDT)", "url" : "/", "views" : 3 }
Temos a informação do dia e hora e da quantidade de visitas em cada página. Suponha que os dados são coletados a cada hora. Para as visitas totais ao site temos uma collection separada, chamada de hourly_totals com as informações abaixo.
{ "hour" : "Tue Jun 15 2010 9:00:00 GMT-0400 (EDT)", "views" : 10 }
{ "hour" : "Tue Jun 15 2010 10:00:00 GMT-0400 (EDT)", "views" : 25 }
{ "hour" : "Tue Jun 15 2010 11:00:00 GMT-0400 (EDT)", "views" : 24 }
Vamos agora criar a função track que, toda vez que o site receber uma visita, a hora será armazena e o número de views será incrementado em uma unidade. Nossa collection aqui é a hourly_totals.
from datetime import datetime
def track(url):
hour = datetime.utcnow().replace(minute=0, second=0, microsecond=0)
db.hourly.update({"hour": hour, "url": url},
{"$inc": {"views": 1}}, upsert=True)
db.hourly_totals.update({"hour": hour},
{"$inc": {"views": 1}}, upsert=True)
O trecho de código datetime.utcnow().replace(minute=0, second=0, microsecond=0) caputra as informações de data e hora no momento em que é executado e "elimina" as informações de minutos, segundos e micro segundos, resultado apenas no formato desejado para a collection.
O próximo passo é criar um índice para nossas consultas nas duas collections. Uma descrição mais detalhada pode ser encontrada em nosso post Índices no MongoDB e o Comando explain() - CRUD Operations - Parte 2
from pymongo import ASCENDING
db.hourly.create_index([("url", ASCENDING), ("hour", ASCENDING)], unique=True)
db.hourly_totals.create_index("hour", unique=True)
A primeira etapa, de inserir informações no banco de dados está concluída. A próxima é criar o trecho de código que fazer uma consulta no banco e calcula a quantidade de visitas em cada uma das últimas 10 horas.
from pymongo import DESCENDING
for rollup in db.hourly_totals.find().sort("hour", DESCENDING).limit(10):
pretty_date = rollup["hour"].strftime("%Y/%m/%d %H")
print "%s - %d" % (pretty_date, rollup["views"])
A variável pretty_date recebe a data formatada para ser exibida de um modo mais fácil de se entender. Repare também que fazemos uma ordenação na informação das horas (hour), alinhada com o índice que foi criado anteriormente.
Um abraço e até o próximo post!
Adaptado de: “MongoDB: The Definitive Guide by Kristina Chodorow and Michael Dirolf (O’Reilly). Copyright 2010 Kristina Chodorow and Michael Dirolf, 978-1-449-38156-1.”
0 comentários:
Postar um comentário