sql >> Base de Datos >  >> NoSQL >> MongoDB

Función MapReduce en MongoDB - Documento de agrupación por ID

En su aprendizaje, es posible que se haya perdido la página principal del manual en mapReduce . Hay una pieza vital de información que te perdiste o que no leíste y aprendiste:

Y luego un poco después de eso:

Entonces, lo que eso significa básicamente es que debido a que el "reductor" en realidad no procesa "todas" las claves únicas a la vez, entonces espera la misma "entrada" que da "salida", ya que esa salida se puede realimentar en el reductor de nuevo.

Por la misma razón, el "mapeador" necesita generar exactamente lo que se espera como salida del "reductor", que también es la "entrada" del reductor. Por lo tanto, en realidad no "cambia" la estructura de datos en absoluto, sino que simplemente la "reduce".

db.Cool.mapReduce(
    function(){emit(this.id, { "cools": [this.cool] })},
    function(key, values){
        var res = [];
        values.forEach(function(cool){
            cool.cools.forEach(function(v) {
                res.push(v);
            });
        });
        return {cools: res};
    },
    {out: "MapReduce"}     
)

Ahora está manejando la entrada como una matriz que también es la salida, luego se devuelven los resultados esperados.

Lo siguiente que debe aprender es que en la mayoría casos, mapReduce no es realmente lo que desea usar, y debería usar marco de agregación en su lugar.

A diferencia de mapReduce, este utiliza operadores "codificados de forma nativa" y no necesita la interpretación de JavaScript para ejecutarse. Y eso significa en gran medida que es "más rápido" y, a menudo, mucho más simple en la construcción.

Aquí está la misma operación con .aggregate() :

db.Cool.aggregate([
    { "$group": {
        "_id": "$id",
        "cools": { "$push": "$cool" }
    }}
])

Lo mismo, menos codificación y mucho más rápido.

Al enviar a otra colección, usa $out :

db.Cool.aggregate([
    { "$group": {
        "_id": "$id",
        "cools": { "$push": "$cool" }
    }},
    { "$out": "reduced" }
])

Para el registro, aquí está la salida de mapReduce:

{ "_id" : "a", "value" : { "cools" : [ "a1", "a2" ] } }
{ "_id" : "b", "value" : { "cools" : [ "b1", "b2" ] } }
{ "_id" : "c", "value" : { "cools" : [ "c1" ] } }
{ "_id" : "d", "value" : { "cools" : [ "d1" ] } }

Y la producción agregada. Con la única diferencia del mapReduce _id y value la salida obligatoria es que las teclas están invertidas, ya que $group no garantiza un pedido (pero generalmente se observa como una pila inversa):

{ "_id" : "d", "cools" : [ "d1" ] }
{ "_id" : "c", "cools" : [ "c1" ] }
{ "_id" : "b", "cools" : [ "b1", "b2" ] }
{ "_id" : "a", "cools" : [ "a1", "a2" ] }