2010-06-08 13 views
7

Ho scritto una MapReduce in MongoDB e vorrei usare una variabile globale come cache per scrivere/leggere da. So che non è possibile avere variabili globali attraverso istanze di funzioni di mappa - Voglio solo una variabile globale all'interno di ogni istanza di funzione. Questo tipo di funzionalità esiste in MapReduce di Hadoop quindi mi aspettavo che fosse lì in MongoDB. Ma quanto segue non sembra funzionare:MongoDB MapReduce: variabili globali all'interno dell'istanza della funzione mappa?

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'; 
    } 
} 

È questo il non ammessi nell'attuazione MapReduce di MongoDB, o sto facendo qualcosa di sbagliato in JavaScript (non esperto in JS)?

+0

OK, ho sfogliò di nuovo e v'è un punto di confusione qui. Questa funzione è la tua mappa o la tua riduzione? Se si desidera una cache "ad hoc", è sufficiente creare una raccolta temporanea in Mongo e fare riferimento alla mappa o ridurre. Tuttavia, senza conoscere sia la mappa() e ridurre() funziona è difficile da dire, se non si può semplicemente risolvere questo problema in fase di riduzione. –

+0

Questa è la funzione della mappa. Potrei farlo alla funzione di riduzione ma ho altre cose che devo fare a quel punto, cioè aggregare alcuni valori. Potrei anche creare una raccolta in MongoDB per fungere da cache - in effetti è quello che ho fatto in primo luogo. Tuttavia questa non è una soluzione ideale (i problemi di blocco se ci sono più istanze di funzioni di mappe possono rallentare) + questa è una funzionalità già presente in MapReduce di Hadoop, quindi lo aspettavamo anche qui. Sentiti libero di chiamarmi un nitpicker, ma credo che sia qualcosa che deve essere risolto in MongoDB. –

risposta

5

Guardando il docs, mi sto trovando la seguente:

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

penso che variabile "scope" è quello che serve.

C'è un test/esempio on Github che utilizza la variabile "ambito".

Sono ancora nuovo in questa roba, ma spero che sia sufficiente per iniziare.

+0

Grazie - ma no, l'ambito non è globale di lettura/scrittura, solo lettura. A proposito, questo esempio sembra non utilizzare la variabile xx che l'ambito sta passando alla mappa/riduce le funzioni. –

+1

Le variabili * in * l'ambito sono perfettamente scrivibili. –

+0

Il link github è morto – zella

1

Come ha detto Gates VP, è necessario aggiungere la cache in ambito globale. Così, per fornire risposta completa, considerando lo script, questo è ciò che è necessario fare:

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

Il comando inietterà contenuto del parametro oggetto 'ambito' nel vostro contesto globale. La memorizzazione nella cache funzionerà quindi per come la utilizzi nella funzione della mappa. Ho provato questo.