lunes, 29 de noviembre de 2010

MongoDB: Un ejemplo de MapReduce

Conceptos de MapReduce
MapReduce es una característica importante comprendida por MongoDB. Este framework fue creado por Google para dar solución a la computación paralela sobre grandes colecciones de datos en sistemas distribuídos. El concepto se basa en dos funciones, map y reduce, que se aplican sobre datos estructurados en formato de pares clave-valor.

La función map (mapeo) toma uno de estos pares en un dominio de datos, y retorna una lista de pares en un dominio diferente. Se aplica en paralelo por cada elemento de la entrada de datos, produciendo la lista de pares por cada llamada, juntando todos los pares con la misma clave de todas las listas y los agrupa, creando un grupo por cada clave.

La función reduce (reducción) se aplica paralelamente a cada grupo, generando una colección de valores para cada dominio, produciendo un valor (o varios) en cada llamada.

Básicamente, MapReduce transforma una lista de pares clave-valor en una lista de valores.


Un ejemplo
Para comprender cómo funciona MapReduce, vamos a ver un ejemplo práctico. Para ello, voy a utilizar uno ya hecho por Kristina Chodorow, una de las principales creadoras de MongoDB.

Imaginemos que tenemos una colección posts, que almacena los artículos de nuestro blog. Un documento en esta colección podría tener esta estructura:
La clave tags es un array de etiquetas, que permiten categorizar cada artículo. Y sobre esta clave vamos a basar el ejemplo de MapReduce, como por ejemplo, conocer las etiquetas más populares, dando un resultado como éste:
La función map emitirá cada etiqueta (tag), y la contará en la función reduce.

La función map es la siguiente:
Lo primero que hace es comprobar si existe una clave llamada tags, para evitar errores. A continuación realiza un bucle sobre esta clave (por cada elemento del array), emitiendo su nombre y un contador de 1.

La función reduce inicializa un contador a 0 y le añade cada elemento del array current. Al final retorna el contador final:
Para ejecutar ésto, invocaremos al comando mapreduce:
Los parámetros facilitados son:
- mapreduce: Se facilita la colección sobre la que extraer los datos (posts).
- map: Nombre de la función que realizará el mapeo.
- reduce: Nombre de la función que realizará la reducción.
- out: Colección donde se pondrá el resultado.

Finalmente, consultamos la colección tags para mostrar los resultados:


Fuentes consultadas
Concepto de MapReduce en Wikipedia: http://es.wikipedia.org/wiki/MapReduce
Artículo "Contar etiquetas", por Kristina Chodorow: http://cookbook.mongodb.org/patterns/count_tags/