2011-09-18 3 views
5

voglio eseguire questa istruzione SQL su MongoDB:Selezionare distinta più di un campo usando la mappa di MongoDB ridurre

SELECT DISTINCT book,author from library 

Finora MongoDB di DISTINCT supporta un solo campo alla volta. Per più di un campo, dobbiamo usare il comando GROUP o map-reduce.

Googled un modo per utilizzare il comando GROUP:

db.library.group({ 
    key: {book:1, author:1}, 
    reduce: function(obj, prev) { if (!obj.hasOwnProperty("key")) { 
     prev.book = obj.book; 
     prev.author = obj.author; 
    }}, 
    initial: { } 
}); 

Tuttavia questo approccio supporta solo fino a 10.000 chiavi. Qualcuno sa come usare la mappa ridurre per risolvere questo problema?

risposta

4

Dai un'occhiata a questo article che spiega come trovare articoli unici usando map-reduce in MongoDB.

La sua dichiarazione Emit è andare a guardare qualcosa di simile:

emit({book: this.book, author: this.author}, {exists: 1}); 

e il vostro ridurre può essere ancora più semplice che l'esempio dato che non si cura di quanti ce ne sono per ogni raggruppamento.

return {exists: 1}; 
+0

Thanks a lot. Funziona bene. ma ho ancora difficoltà a trovare la funzione di '{exists: 1}'. nella mia comprensione è una specie di identificatore per ogni valore unico. ma lo trovo ancora strano –

+1

In genere il valore è più complesso e ha diversi campi. Potresti semplificare questo per emettere solo un valore 1, ma '{exists: 1}' è più intuitivo e renderà più facile quando vorrà aggiungere più campi ad esso in seguito. –

3

Nel caso in cui qualcuno affronta il problema simile. Questa è la soluzione completa:

mappa PASSO

map= "function(){ 
    emit(
      {book: this.book, author:this.author}, {exists: 1} 
     ); 
    }" 

Ridurre passo

reduce= "function(key, value){ 
      return {exists: 1}; 
    }" 

Eseguire il comando

result= db.runCommand({ 
     "mapreduce": "library", 
     "map": map, 
     "reduce": reduce, 
     "out: "result" 
    }) 

ottenere il risultato

db.result.find()