2010-06-08 6 views
7

Escribí un MapReduce en MongoDB y me gustaría utilizar una variable global como caché para escribir/leer. Sé que no es posible tener variables globales en instancias de función de mapa - Solo quiero una variable global dentro de cada instancia de función. Este tipo de funcionalidad existe en MapReduce de Hadoop, así que esperaba que estuviera allí en MongoDB. Pero el siguiente no se parece funcionar:MongoDB MapReduce: ¿Variables globales dentro de la instancia de función de mapa?

var cache = {}; // Does not seem to work! 
function() { 
    var hashValue = this.varValue1 + this.varValue2; 
    if(typeof(cache[hashValue])!= 'undefined') { 
    // Do nothing, we've processed at least one input record with this hash 
    } else { 
    // Process the input record 
    // Cache the record 
    cache[hashValue] = '1'; 
    } 
} 

No es esto permitido en la implementación de MapReduce de MongoDB, o estoy haciendo algo mal en JavaScript (no experimentado en JS)?

+0

OK, he hojeado esto otra vez y aquí hay un punto de confusión. ¿Es esta función su mapa o su reducen? Si desea un caché "ad-hoc", puede simplemente crear una colección temporal en Mongo y hacer referencia a eso desde el mapa o reducirlo. Sin embargo, sin conocer las funciones map() y reduce() es difícil decir si no puede resolver este problema en la fase de reducción. –

+0

Esta es la función de mapa. Podría hacer esto en la función de reducción, pero tengo otras cosas que debo hacer en ese momento, es decir, agregar algunos valores. También podría crear una colección en MongoDB para servir como caché, de hecho eso es lo que hice en primer lugar. Sin embargo, esta no es una solución ideal (problemas de bloqueo si hay varias instancias de función de mapa pueden desacelerar) + esta es una función que ya existe en MapReduce de Hadoop, por lo que también la esperaba aquí. Siéntase libre de llamarme un pesimista, pero creo que es algo que debe corregirse en MongoDB. –

Respuesta

5

Mirando el docs, estoy encontrando lo siguiente:

db.runCommand(
{ mapreduce : <collection>, 
    map : <mapfunction>, 
    reduce : <reducefunction> 
    [, scope : <object where fields go into javascript global scope >] 
} 
); 

creo que esa variable "alcance" es lo que necesita.

Hay una prueba/ejemplo on Github que usa la variable "scope".

Todavía soy nuevo en esto, pero espero que sea suficiente para comenzar.

+0

Gracias, pero no, el alcance no es global de lectura/escritura, solo lectura. Por cierto, este ejemplo parece no estar usando la variable xx que el alcance está pasando a las funciones de mapa/reducir. –

+1

Las variables * en * el alcance son perfectamente escribibles. –

+0

enlace github está muerto – zella

1

Como dijo Gates VP, debe agregar el caché al alcance global. Por lo tanto, para proporcionar respuesta completa, teniendo en cuenta la secuencia de comandos, esto es lo que necesita hacer:

db.runCommand(
{ mapreduce : <your collection>, 
    map : <your map function, or reference to it>, 
    reduce : <your reduce function, or reference to it>, 
    scope : { cache : {} } 
} 
); 

El comando inyectará contenido del parámetro del objeto 'alcance' en su contexto global. El almacenamiento en caché funcionará de acuerdo con la forma en que lo esté utilizando en su función de mapa. He probado esto

Cuestiones relacionadas