MongoDB

Qué trae MongoDB 2.6 para los desarrolladores

Ahora que la versión 2.6 de MongoDB ha sido liberada, quiero explicar en términos generales aquellas características que desde el punto de vista de un desarrollador deben tenerse en cuenta. Esta versión es la más grande que hasta ahora se ha liberado, por lo que es muy emocionante hablar de ella.

Full Text Search

Full Text Search o Búsqueda de texto completo ahora estará completamente soportada y lista para ser usada en ambientes de producción.

Para ser exactos, esta característica fue introducida en la versión 2.3.2 (Versión de desarrollo 2.4) y para poder ser utilizada debía ser activada por medio del parámetro textSearchEnabled. Full Text Search en MongoDB es soportado con muchos idiomas, incluyendo el español, por lo que va a ser muy divertido crear aplicaciones que hagan uso de esta funcionalidad.

MongoDB otorga esta funcionalidad con la ayuda de la librería Snowball, que es una librería escrita en C que proporciona stemming.

Mejoras en Aggregation Framework

Cursores como resultado de agregación

Anteriormente MongoDB sólo podía retornar un documento como resultado de una operación de agregación, por lo que probablemente estábamos forzados a incluir un operador $limit al final de nuestro pipeline para no exceder el tamaño límite de un documento, que es 16MB.

En cambio, ahora es posible recibir un cursor para una operación de agregación estableciendo como segundo parámetro la opción “cursor”, y como valor de esta clave, un objeto que señale el tamaño inicial del lote con la clave “batchSize”.

> db.coleccion.aggregate([ … ], { cursor: { batchSize: 0 } })

Este tamaño le especifica al servidor el número de documentos que deberá retornar en el primer lote; de tal manera que si le establecemos 0 como en el ejemplo, nos servirá para obtener una respuesta satisfactoria o de error con el más mínimo esfuerzo para tus instancias de MongoDB. Ten en cuenta que es algo muy similar a lo que podemos establecer con el método batchSize, con la única diferencia afecta sólo al primer lote retornado en el cursor.

Explain para agregación

También ahora puedes aprovechar que Aggregation Framework es capaz de retornar la información de una consulta. Al igual que para recibir un cursor como resultado, el método aggregate evalúa el segundo parámetro buscando la clave “explain”, de esta manera:

> db.coleccion.aggregate([ … ], { explain: true })

El método aggregate considera que el primer parámetro es el pipeline siempre y cuando sea un array, en caso contrario considera que el pipeline es un array que tiene agrupado a todos los parámetros con los que el método es invocado. Así que siempre que quieras utilizar las opciones para este método, es necesario que te asegures que el primer parámetro es realmente un array.

Resultado hacia una colección

El resultado de una operación de agregación ahora también puede ser escrita en una colección nueva o existente. Puedes incluir al final del pipeline de agregación un objeto con un operador $out, este operador debe siempre poseer como valor una cadena que indique el nombre de la colección que será utilizada para escribir los resultados.

Así por ejemplo, en la siguiente operación, los resultados serían insertados en una colección llamada “resultante”:

> db.coleccion.aggregate([ … , { $out: “resultante” }])

Si la colección donde serán insertados los resultados existe, los documentos que tenga esta colección serán reemplazados por el resultado de la operación de agregación; cabe mencionar que esto no modificará los índices que ya podría tener creados. Por el contrario, si se trata de una colección que no existe, simplemente es creada. Asimismo, hay que tener en consideración que el resultado no puede ser escrito en una colección con tope.

Operadores de conjuntos

O también llamados “set operators”, estos operadores como su nombre bien los menciona son utilizados para realizar operaciones de conjuntos en el pipeline de agregación.

Existen operadores para obtener la diferencia entre conjuntos, también la inclusión, la diferencia, la unión y la comparación. Puedes ver la especificación de todos estos operadores en el Manual.

Mejoras en operaciones actualización

Operadores $max y $min

Estos son operadores condicionales, los cuales pueden ser aprovechados para actualizar campos atómicamente.

Por ejemplo, en nuestras aplicaciones, si antes primero teníamos que consultar un documento, luego evaluar su contenido y finalmente realizar la actualización; quizás algo muy parecido a esto (En Python):

>>> min = 400
>>> doc = db.coleccion.find_one(criterio)
>>> db.coleccion.update(criterio, {”$set": {"campo": min if min < doc['campo'] else doc['campo']}})

De esa manera no se podía asegurar que en un escenario de alta concurrencia, tengamos exactamente el valor que deseamos. Ahora, lo podemos hacer simplemente ejecutando la siguiente operación:

>>> min = 400
>>> db.coleccion.udpate(criterio, {“$min”: min})

Los objetivos son los mismos para $max y $min, el valor del campo se establecerá de acuerdo a si se desea modificar por el mayor o menor valor, entre el existente y el nuevo que se está enviando en la actualización.

Operador $mul

Al igual que $min y $max, $mul funciona atómicamente y es ideal para el uso en escenarios concurrentes. Lo que hace este operador es aplicar una multiplicación al valor existente del campo que se desea actualizar. Por ejemplo, si deseo multiplicar el valor existente por 5, sería algo así:

>>> factor = 5
>>> db.coleccion.update(criterio, {“$mul”: factor})

Tener en cuenta que si el campo que desea ser actualizado no existe en el documento, el producto que obtendrá será 0.


Estas y otras características que vienen con MongoDB 2.6 están relatadas en el documento de notas de versión en el Manual de MongoDB. Visita siempre el Manual, ahí se encuentra siempre bien documentados, los cambios y las nuevas funcionalidades.

Standard
Review

Review of Learning Apache Maven 3

The first chapter of Learning Apache Maven 3 screencast video series of Packt Publishing starts by explaining the installation process on Windows operating system, Linux, and Mac OSX. Also the videos shows the way to configure Maven on Eclipse IDE by downloading the m2eclipse plugin, on IntelliJ IDEA 12.0.4, and NetBeans 7.3. Eclipse is the selected IDE for the author to show all examples. These videos are really quick and they’ll seems like the time goes very fast but they are very well explained.

In the beginning of each section/chapter, the author mentions the agenda listing all that is to be treated. In the second section he shows how to create an application using the Maven Archetype plugin, curiously before going on the implementation of the example, the author claims in the core concepts and terminology after the flow graph which manages to make this creation.

The examples of the usage of the plugin shown creating an application, unit tests integration tests. After that, shows an example for web applications, dependencies management, integration with Struts2, Hibernate, Spring, and Tomcat.

Finally, the videos shows the creation of a multi-module project, to be exact 4 modules: a Multimodule Parent, a WebService, a WebService client, and a WebApplication, and in two ways: using a flat structure and a structure with inheritance; explaining the architecture and core concepts such as Aggregation Project, Build, Inheritance.

In my view, the videos are pretty good for people trying to learn things a little off the beaten path, I found it very interesting to see things such as search.maven.org central repository and the specifying the scopes of all libraries in the modules. Also, at first glance, the videos could not prove to be attractive to professionals who have extensive experience with Maven, because it contains tutorials showing a way how to start and is not a cookbook.

Standard
MongoDB

Traducción del curso M101P al español

Para describir el proceso de traducción de M101P: MongoDB for Developers al español, tenemos que retroceder en el tiempo cerca de 11 meses. A inicios de diciembre del año pasado empezamos la traducción de la documentación de MongoDB (más conocida como el Manual de MongoDB), llegando a alcanzar más de 70000 palabras traducidas en seis meses y redactando un listado de convenciones de términos de MongoDB (y otros términos técnicos) en español. Las 70000 palabras traducidas resultan el 26% del manual, que por cierto es el más alto porcentaje traducido entre todos los idiomas. Y cuando dije “nosotros”, me estuve refiriendo a Juan Carlos Farah, Jose Carlos García y a mí, quienes hemos intercambiado muchos mensajes de correo y discutido términos, que puedan ser cómodamente usados en la mayoría de los dialectos, para después incluirlos en la traducción final. Asimismo hemos recibido la ayuda de otros amigos, Francisco Fernández de Pedro, un colega de José Carlos y A. Perez.

El inicio

Aunque sabíamos que traducir la documentación era una gran contribución para la comunidad de MongoDB, acordamos traducir el material de uno de los cursos de MongoDB University, pensamos que con esto alentaríamos a más hispanohablantes a participar en el curso hasta el final. De hecho, dado que este curso es un punto de partida para muchos principiantes con MongoDB; deseamos mostrar a la comunidad, que MongoDB tiene un buen soporte en español. Así que en el MongoDB Days NYC, contagiados por el positivo ambiente de la conferencia, Juan Carlos y yo nos acercamos a Andrew Erlichson con la idea. Él pensó que sería una gran oportunidad para expandir el alcance de MongoDB y estuvo contento ya que la iniciativa proviene de la misma comunidad. Luego de un debate inicial, decidimos traducir M101P, que iba a ser ofrecido en los finales del verano, por lo que el equipo se puso a trabajar.

Con el permiso de MongoDB, hemos hospedado el proyecto en GitHub. GitHub juega un papel muy importante porque nos provee un buen manejo de archivos, comunicación ágil y excelentes herramientas para dar seguimiento al progreso y a los cambios. También, nos brinda la posibilidad de recibir retroalimentación de la comunidad y todos están bienvenidos a contribuir. Nuestro proyecto ha sido denominado “Subte”, que en realidad es un juego de palabras que se le ocurrió a Juan Carlos. Puede significar “Subterráneo” (“Subway” en inglés), un homenaje a Nueva York, donde el proyecto fue concebido y a la vez suena mucho como “Subtítulos”, que es de lo que se trata el proyecto.

El proceso

El flujo de trabajo que usamos fue establecido naturalmente y con eso quiero decir a que a nadie se le ocurrió antes, sino que se convirtió en la mejor manera de hacer las cosas a medida que avanzábamos. Básicamente consiste en lo siguiente:

  1. Cada persona crea un issue y se asigna a sí mismo un cierto número de lecciones a traducir.
  2. Todas la traducciones se realizan en nuestros propios forks para las lecciones que nos asignamos.
  3. Al terminar, enviábamos un pull request para cada issue.
  4. Antes de hacer el merge del pull request, discutíamos y sugeríamos cambios.
  5. Si era necesario, la persona quien enviaba el pull request hacía los cambios.
  6. Se repetía de 3 a 5 veces, según sea necesario.
  7. Se hacía merge al pull request.

Este flujo fue realizado por milestones, cada milestone equivale a una semana del curso. Pot último, antes de entregar los subtítulos de un milestone a MongoDB University, Juan Carlos hacía una revisión final de los subtítulos para normalizar el idioma y realizar mínimas tareas de edición.

Los principales beneficios que obtuvimos realizando la traducción de la manera descrita fueron:

  • Mejor calidad de traducción, ya que el flujo de trabajo diseñado requiere que todos nosotros revisemos todos los subtítulos en absoluto.
  • Fuerte consistencia de los subtítulos, realizando una revisión final antes de enviarlos cada semana.
  • Coordinación y flujo de trabajo ágil, evitando hacer retrabajo y no duplicando esfuerzos.
  • Mayor neutralidad, considerando múltiples dialectos del idioma.

Adicionalmente, el proceso por completo fue manejado usando Kanban y específicamente Huboard, que fue genial para manejar los issues de GitHub. Aunque el tablero ahora está en blanco, la captura a continuación explica cómo estuvimos trabajando en la primera versión.

Subte-M101P-Huboard01

Conclusión

Recientemente ¡la primera versión de la traducción de los subtítulos ha sido liberada! Esta fue la versión usada durante la última ronda de M101P: MongoDB for developers (Setiembre – Octubre 2013). Puedes encontrarla en GitHub y estaremos agradecidos de recibir cualquier sugerencia, comentarios o pull requests.

También hemos estado participando como asistentes de enseñanza en el foro del curso, así que ¡esperamos verte en las siguientes rondas de M101P o de otros cursos!

La siguiente ronda de este curso inicia el 25 de noviembre.

Reconocimiento a los contribuidores

José Carlos es de España. Él se unió al equipo motivado por su propio interés luego de tomar el curso para DBAs en su primera ronda. Asimismo es un contribuidor del proyecto Fedora, por lo que ya sabemos que tiene mucha disciplina y esfuerzo en actividades de este tipo de ecosistemas.

Juan Carlos es de Perú, como yo, él aceptó amablemente una invitación para la traducción que publiqué en el Grupo de usuarios de MongoDB de Perú. Él tuvo experiencia traduciendo textos mientras estudiaba en la Universidad de Harvard, así que confiamos es su juicio y purismo; tanto así que revisó esta publicación también.

Standard
MongoDB

Translation of the M101P course into Spanish

In order to describe the process of translating M101P: MongoDB for Developers into Spanish, we have to go back in time about 11 months. In early December of last year, we started translating the MongoDB documentation (commonly known as the MongoDB Manual), achieving more than 70,000 translated words in six months and drafting a list of conventions for MongoDB (and other technical) terms in Spanish. The 70,000 translated words roughly accounts for 26% of the manual, which is the highest percent translated into any language. By we, I’m referring to Juan Carlos Farah, Jose Carlos García and myself, exchanging many emails and discussing terms cross-dialect normalisations before committing to a final translation. We also received help from other friends, Francisco Fernández de Pedro, a colleague of Jose Carlos, and A. Perez.

Beginning

Though we knew that translating the documentation was a great contribution to the MongoDB community, we agreed that by translating the material from one of MongoDB University’s courses, we would encourage more Spanish speakers to see the course through to the end. In fact, given that the course is a common starting point for many MongoDB beginners, we wanted to show the community that MongoDB had good Spanish support. So at MongoDB Days NYC, inspired by the positive atmosphere of the conference, Juan Carlos and I approached Andrew Erlichson with the idea. He thought that it would be a great opportunity to expand MongoDB’s reach and was happy to see the initiative come from the community itself. After some initial debate, we decided to translate M101P, which was going to be offered towards the end of the summer, and so the team got to work.

With permission from MongoDB, we hosted the project on GitHub. GitHub plays a very important role because it provides for good file management, streamlined communication and excellent tools to track progress and diffs. Also, it enables us to receive feedback from the community and everyone is welcome to contribute. Our project has been dubbed “Subte”, which actually is a play on words that Juan Carlos came up with. It can stand for “Subterráneo” (“Subway” in Spanish), a homage to New York, where the project was conceived, and sounds a lot like “Subtitles”, which is what the project is about.

The process

The workflow that we used was established naturally, and by that I mean that no one came up with it beforehand, but it became the best way to do things as we progressed. It basically consists of the following:

  1. Each person created an issue and assigned himself a certain number of lessons to translate.
  2. All translations were done in each of our own forks for the lesson that we assigned.
  3. Upon completion, we would send a pull request for each issue.
  4. Before merging the pull request, we would discuss and suggest potential changes.
  5. If necessary, the person who sent the pull request made the changes.
  6. Repeat 3-5 as necessary.
  7. Merge the pull request.

This workflow was done by milestones, with each milestone equivalent to a week of the course. Finally, before delivering the subtitles of a corresponding milestone to MongoDB University, Juan Carlos made a final review of the subtitles to normalize the language and perform minor editorial tasks.

The main benefits that we obtained by performing the translation in the manner described above, were:

  • Better translation quality, since the workflow designed requires that all of us review all of the subtitles.
  • Greater consistency across subtitles by performing a final revision before each weekly submissions.
  • Smoother coordination and workflow, avoiding doing work twice and duplicate assignments.
  • More neutrality by considering multiple dialects and idioms.

Additionally, the whole process was monitored using a Kanban and specifically Huboard, which was great to manage the issues on GitHub. Though the board is now blank, below is a screenshot from when we were working on the first version.

Subte-M101P-Huboard01

Conclusion

Recently the first version of the subtitle translation has been released! This was the one used during the last round of M101P: MongoDB for developers (September – October 2013). You can find it on GitHub and we would be very grateful to receive any suggestions, comments or pull requests.

We’ve also been participating as teaching assistants in the course forum, so we hope to see you in future offering of M101P or of the other courses!

The next round of this course starts on November 25th.

Acknowledgments to the contributors

José Carlos is from Spain. He joined the team motivated by self-interest after taking the course for DBAs in its first offering. He’s also a contributor for the Fedora project, so we already know he has a lot of discipline and effort in activities for this kind of ecosystems.

Juan Carlos is from Peru, like me, and he kindly accepted an invitation to translate that I published in the MongoDB User Group Peru. He had experience translating texts while studying at Harvard University, so we trust his judgment and purism; so much so that he reviewed this post as well.

Standard
Python

wtforms-tornado: WTForms extensions for Tornado

Earlier this year I took up the development of a simple CMS for blogging, this project was just an attempt to play with Tornado and MongoDB, and one issue that was bugging me was the validation of the arguments of the HTTP request, I had to do nested and gigantic conditions, it was something really annoying. I started with something like this:

import tornado.web
import tornado.ioloop

class RegisterHandler(tornado.web.RequestHandler):

    def post(self):
        username = self.get_argument('username', None)
        password = self.get_argument('password', None)
        if username and password:
            self.write('Ok!')
        else:
            self.write('Invalid request!')

if __name__ == '__main__':
    tornado.web.Application([('/', RegisterHandler)]).listen(8888)
    tornado.ioloop.IOLoop.instance().start()

And as you can see this is quite basic, and what about if I want to validate data types, length, a regular expression, choices, etc, etc, etc, it would be really extensive.

The first thing I thought as a solution for this was WTForms, WTForms would help me to avoid these conditions and form fields rendering in templates. But what happened when I started to use it?

import tornado.web
import tornado.ioloop
import wtforms

from wtforms.fields import StringField, PasswordField
from wtforms.validators import Required

class RegisterForm(wtforms.Form):

    username = StringField(validators=[Required()])
    password = PasswordField(validators=[Required()])

class RegisterHandler(tornado.web.RequestHandler):

    def post(self):
        form = RegisterForm(self.request.arguments)
        if form.validate():
            self.write('Ok!')
        else:
            self.write('Invalid request!')

if __name__ == '__main__':
    tornado.web.Application([('/', RegisterHandler)]).listen(8888)
    tornado.ioloop.IOLoop.instance().start()

It looks very simple to do but the arguments attribute of the request is a naive dictionary and is not what WTForms expects to access the data. The exception and traceback obtained by invoking the validate method were:

ERROR:tornado.application:Uncaught exception POST / (127.0.0.1)
HTTPRequest(protocol='http', host='localhost:8888', method='POST', uri='/', version='HTTP/1.1', remote_ip='127.0.0.1', headers={'Host': 'localhost:8888', 'Accept': '*/*', 'User-Agent': 'curl/7.29.0'})
Traceback (most recent call last):
  File "/home/puentesarrin/virtualenvs/wtforms-tornado/local/lib/python2.7/site-packages/tornado/web.py", line 1141, in _when_complete
    callback()
  File "/home/puentesarrin/virtualenvs/wtforms-tornado/local/lib/python2.7/site-packages/tornado/web.py", line 1162, in _execute_method
    self._when_complete(method(*self.path_args, **self.path_kwargs),
  File "wtforms-tornado.py", line 18, in post
    form = RegisterForm(self.request.arguments)
  File "/home/puentesarrin/virtualenvs/wtforms-tornado/local/lib/python2.7/site-packages/wtforms/form.py", line 178, in __call__
    return type.__call__(cls, *args, **kwargs)
  File "/home/puentesarrin/virtualenvs/wtforms-tornado/local/lib/python2.7/site-packages/wtforms/form.py", line 233, in __init__
    self.process(formdata, obj, **kwargs)
  File "/home/puentesarrin/virtualenvs/wtforms-tornado/local/lib/python2.7/site-packages/wtforms/form.py", line 102, in process
    raise TypeError("formdata should be a multidict-type wrapper that supports the 'getlist' method")
TypeError: formdata should be a multidict-type wrapper that supports the 'getlist' method
ERROR:tornado.access:500 POST / (127.0.0.1) 15.63ms

Well, arguments doesn’t implement the “getlist” method, which is expected to return a list of values ​​for a given key. So I sent a pull request two weeks ago, for adding an extension to the core of WTForms.

But unfortunately the WTForms team is interested on removing the extensions, and after recommendation from @crast I created the module wtforms-tornado which can be located on PyPI and GitHub. All suggestions are welcome!

Standard
Review

Review of Instant Apache Solr for Indexing Data How-to

This book starts with a good intention that the author defined, I mean he clearly points to what the book is done and the way in which the reader will travel.

One of the first things I liked is that the examples are on GitHub, this gives us the facility to have a feedback to the author. All examples have been carefully categorized according to the level of complexity, from simple to advanced.

It is amazing that Alexandre Rafalovitch (the author) has obviated the Solr installation process in the book, since it is a readily available resource and too trite in every book, not just for Solr, as many authors have dealt largely a chapter on this subject, while Alexandre tries to go straight to the heart of how to use Solr.

The author mentions also many tips and tricks for a quick fix common mistakes that can have as beginners, he has combined nicely presenting examples throughout the book with practical and useful tips.

I must congratulate Alexander for doing a great job, I’m usually very sharp to find errors in the book and in this I have not been able to do. This book has a lot of readability and comprehensibility, this is a key point to consider the book for learning Solr.

DISCLAIMER:

My preference for using Solr is not involved in my general appreciation for this book.

Standard
Python

Bonzo: Minimalistic Python SMTP Proxy

In this week, I built Bonzo, a minismalistic SMTP Proxy built on top of Tornado.

The motivation was that in my current job, we need to do tests on email messages that are sent through our applications. It all started when I saw a GitHub repository that has the first component that we need: an SMTP server, I did a couple of tests and unfortunately I did not have good results, something that not convinced me was the inactivity of the project because it had more than 3 years without having maintenance –although it was not necessary because the protocol has not changed.

Then, a co-worker recommended me to review the smtpd module, and since I’m very stubborn in wanting to use Tornado for all… the next night I decided not to sleep until I have done an SMTP server with all that smtpd implemented based on the code repository that I found at the beginning.

The result was basically an implementation of smtpd to extend the Tornado’s TCPServer class. An example of how to use Bonzo is, as follow:

TODO:

  • Authentication: Probably I will provide a method hook for verify the athentication and to derivate the responsability to a implementor’s logic.
  • TSL: I should to implement a way to support the STARTTLS command.
  • Unit tests!

Links:

P.S.

About the name… I have selected “Bonzo” because it’s the nickname of the drummer of my favorite Rock band and the best world’s drummer.

Standard
Review

Review of Instant Apache ActiveMQ Messaging Application Development How-to

This book begins by describing the basic installation process, then mentions some ActiveMQ usage patterns and ends by considering other useful issues for proofs of concept and unit testing with ActiveMQ. The author has taken great care in drafting and each chapter describes the topic shows the code and explains something additional concerning the topic.

My recommendation to the author is:

  • Consider using GitHub to post the source code for the examples, the code version control are very useful for referencing code and to receive feedback from readers.
  • Give use cases for the patterns, throughout the book are mentioned different patterns and at least should be mentioned a use case for each.

The latter is something I would like to extend, for example mentions a request/response pattern, and, I personally have never heard of this with a message broker, here is a simple example of how to develop it but the best way to explain this would be a use case. It is clearly understood that doing this is not scalable in a single process to wait for the answer “in one thread”, but, what concerns should lead someone to do this?, In fact, always think this (in my opinion) we helps to make everything asynchronously and is what message brokers are made.

I must admit that the author also considered to mention two ActiveMQ aspects that stand out compared to the features of other brokers, I mean Failover transport and Virtual destinations, these are two issues that never would have expected to be included in a book, and however I must congratulate the author for having an excellent idea.

In short, the book is good enough to be an “Instant” edition, just little things to improve.

UPDATE:
The author has kindly uploaded the code examples to GitHub:

https://github.com/tabish121/ActiveMQ-HowTo

Standard
Review

Review of Instant RabbitMQ Messaging Application Development How-to

The book is truly an “instant book” because it has very practical examples and real use cases for AMQP implementations with Node.js platform. (You could use any language/platform, but it is always good to learn a new one; at least for me, it is perfect!).

In the early chapters, it describes the process of installing RabbitMQ and Node.js, easily and efficiently.

In the following chapters, the author begins by describing a use case where we can use the AMQP protocol, then describes (step by step) the implementation process and finally shows some sample code. Among the cases presented by the author are: an e-commerce & inventory application and a logging application.

Also, the code examples presented in the book are well maintained by the author and can be viewed and edited on GitHub: https://github.com/AndrewKeig/rabbitmq-messaging-application-development

Other final notations are mentioned, including: Clustering, connections & reconnections, hosting, architecture & performance.

The book also includes many tips and valuable concepts that can be used by the reader. The book is quite understandable, and certainly, as mentioned in the preface, it is not necessary to have any previous knowledge of AMQP, RabbitMQ and Node.js.

You can find the table of contents on PacktPub website: http://www.packtpub.com/rabbitmq-messaging-application-development/book

Standard
MongoDB, Python

PyMongoLab: Cliente Python para el REST API de MongoLab

Hace casi un par de semanas, en un tiempo en el que leí acerca del driver oficial de Python para MongoDB; vi que era posible hacer un módulo que tenga una sintaxis muy parecida a este driver y que consuma los métodos expuestos por el REST API de MongoLab: http://support.mongolab.com/entries/20433053-rest-api-for-mongodb.

Bien, el resultado fueron 2 pequeños módulos en el que el primero utiliza urllib2 para acceder al REST API y el segundo que es wrapper del primero para utilizar la sintaxis que deseaba; este proyecto lo alojé en GitHub y la documentación -en inglés- se encuentra en la siguiente dirección:

Aquí unos ejemplos de uso:

Conexión a REST API

>>> from pymongolab import Connection, database, collection
>>> con = Connection("MongoLabAPIKey")
>>> db = database.Database(con, "database")
>>> collection.Collection(db, "collection")
Collection(Database(Connection('MongoLabAPIKey', 'v1'),
'database'), 'collection')

Consulta de documentos

>>> from pymongolab import Connection
>>> con = Connection("MongoLabAPIKey")
>>> con.database.collection.find()
>>> list(con.database.collection.find())
[{u'_id': ObjectId('50243d38e4b00c3b3e75fc94'), u'foo': u'bar',
u'tld': u'com'}, {u'_id': ObjectId('50004d646cf431171ed53846'),
u'foo': u'bar', u'tld': u'org'}]

Inserción de documentos

>>> doc = {"foo": "bar"}
>>> docs = [{"foo": "bar"}, {"foo": "bar"}]
>>> from pymongolab import Connection
>>> con = Connection("MongoLabAPIKey")
>>> #Inserting a document
... con.database.collection.insert(doc)
{u'foo': u'bar', u'_id': ObjectId('50242e46e4b0926293fd4d7c')}
>>> #Inserting documents
... con.database.collection.insert(docs)
{u'n': 2}

Actualización de documentos

>>> from pymongolab import Connection
>>> con = Connection("MongoLabAPIKey")
>>> list(con.database.collection.find())
[{u'_id': ObjectId('50243d38e4b00c3b3e75fc94'), u'foo': u'bar',
u'tld': u'org'}]
>>> con.database.collection.update({"foo": "bar"},
... {"$set": {"tld": "com"}})
1
>>> list(con.database.collection.find())
[{u'_id': ObjectId('50243d38e4b00c3b3e75fc94'), u'foo': u'bar',
u'tld': u'com'}]
>>> con.database.othercollection.update({"foo":"bar"},
... {"$set": {"tld": "com"}}, multi=True)
6

Eliminación de documentos

>>> from pymongolab import Connection
>>> con = Connection("MongoLabAPIKey")
>>> #Deleting a document
... con.database.collection.remove({"foo": "bar"})
2
>>> #Deleting all documents
... con.database.collection.remove()
22

Este módulo también lo registré en PyPi y dupliqué la documentación en ReadTheDocs:

Standard