2012-06-13 30 views
18

Así soy nuevo con mongodb y mapreduce en general y encontré este "capricho" (o al menos en mi mente una peculiaridad)MongoDB MapReduce - Emitir una clave/valor uno duerma llamar reducir

Decir que tengo objetos en mi colección, así:

{ 'clave': 5, 'valor': 5}

{ 'clave': 5, 'valor': 4}

'llave' { : 5, 'valor': 1}

{ 'clave': 4, 'valor': 6}

{ 'clave': 4, 'valor': 4}

{ 'clave': 3, 'valor': 0}

Mi mapa función simplemente emite la clave y el valor

Mi reducir función simplemente suma los valores y antes de devolverlos añade 1 (Hice esto para comprobar para ver si la función de reducir es e Ven llama)

Mis resultados siguen:

{ '_id': 3, 'valor': 0}

{ '_id': 4, 'valor': 11.0}

{ '_id': 5, 'valor': 11.0}

Como se puede ver, por las teclas 4 5 & me da la respuesta esperada de 11, pero para el th e la clave 3 (con solo una entrada en la colección con esa clave) ¡Obtengo el 0 inesperado!

¿Es este comportamiento natural de mapreduce en general? Para MongoDB? Para pymongo (que estoy usando)?

Respuesta

34

La función reducir combina documentos con la misma clave en un solo documento. Si la función de mapa emite un único documento para una tecla en particular (como es el caso de la clave 3), no se llamará a la función de reducción.

+9

Para que quede claro, esta es la forma en que se diseñó la reducción de mapas. Si desea modificar documentos con claves únicas (como la clave 3), considere utilizar la función de finalización: http://www.mongodb.org/display/DOCS/MapReduce#MapReduce-FinalizeFunction – Jenna

+3

¿cuál es la solución si queremos incluir clave con solo documento en resultados ??? –

+1

@RaviKhakhkhar los documentos únicos todavía se incluyen en los resultados, simplemente las funciones de reducción nunca se llaman en ellos – Cilvic

0

¿Es este comportamiento natural de mapreduce en general?

Sí.

+9

No, esto no es natural para "MR en general". Ni el documento MR original ni Hadoop Map Reduce hacen esto. Es posible que desee convertir ese "1" a otro tipo en el reductor, ¿verdad? Así que, en general, omitir el reductor sería una idea bastante mala/extraña ;-) Esto no significa que el MR de mongo no lo haga, pero no es "el comportamiento esperado en general". –

+0

Aquí http://docs.mongodb.org/manual/tutorial/troubleshoot-reduce-function/ Mongo dice que retuce tiene que devolver el valor del mismo tipo de mapa. Sin embargo, estoy de acuerdo que es malo, peculiar, inesperado y poco claro. – amorfis

4

Comprendo que esto es una cuestión mayor, pero llegaron a la misma y se sentía como yo todavía no entiendo por qué existe este comportamiento y cómo construir un mapa/reducir la funcionalidad por lo que es un no-tema.

La razón por la que MongoDB no llama a la función reducir si hay una sola instancia de una clave es porque no es necesaria (espero que esto tenga más sentido en un momento). Los siguientes son requirements for reduce functions:

  • La función de reducir debe devolver un objeto cuyo tipo debe ser idéntica al tipo del valor emitido por la función de mapa.
  • El orden de los elementos en los valoresArray no debe afectar la salida de la función de reducción
  • La función de reducción debe ser idempotente.

El primer requisito es muy importante y parece que un número de personas que están pasando por alto porque he visto un número de personas en la función de mapeo reducir a continuación, tratar con el caso de clave única en la función de finalización . Sin embargo, esta es la forma incorrecta de abordar el problema.

Piénselo de esta manera: si solo hay una instancia de una clave, una optimización simple es omitir el reductor por completo (no hay nada que reducir). Los valores de clave única todavía se incluyen en la salida, pero la intención del reductor es generar un resultado agregado de los documentos de múltiples claves en su colección. Si el asignador y el reductor están produciendo el mismo tipo, debe ser felizmente inconsciente al observar la estructura de objetos de la salida de las funciones de mapa/reducir. No debería tener que usar una función de finalización para corregir la estructura de sus objetos que no se ejecutó a través del reductor.

En resumen, realice su mapeo en la función de mapa y reduzca los valores multi-clave en un solo resultado agregado en sus funciones de reducción.

3

Solución:

  • añadido nuevo campo en mapa: Habitación individual: 0
  • en reducir cambio de este campo para: Habitación individual: 1
  • en finalizar hacer la comprobación de este campo y realizar las acciones requeridas

    $map = new MongoCode("function() { 
        var value = { 
         time: this.time, 
         email_id: this.email_id, 
         single: 0 
        }; 
    
        emit(this.email, value); 
    }"); 
    
    $reduce = new MongoCode("function(k, vals) { 
    
        // make some need actions here 
        return { 
         time: vals[0].time, 
         email_id: vals[0].email_id, 
         single: 1 
        }; 
    }"); 
    
    $finalize = new MongoCode("function(key, reducedVal) { 
        if (reducedVal.single == 0) { 
         reducedVal.time = 11111; 
        } 
        return reducedVal; 
    };"); 
    
Cuestiones relacionadas