Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select distinct more than one field using MongoDB's map reduce

I want to execute this SQL statement on MongoDB:

SELECT DISTINCT book,author from library

So far MongoDB's DISTINCT only supports one field at a time. For more than one field, we have to use GROUP command or map-reduce.

I have googled a way to use GROUP command:

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: { } 
});  

However this approach only supports up to 10,000 keys. Anyone know how to use map reduce to solve this problem?

like image 996
masu.mo Avatar asked Sep 18 '11 10:09

masu.mo


2 Answers

Take a look at this article which explains how to find unique articles using map-reduce in MongoDB.

Your emit statement is going to look something like:

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

and your reduce can be even simpler than the example since you don't care about how many there are for each grouping.

return {exists: 1};
like image 150
Ian Mercer Avatar answered Nov 14 '22 18:11

Ian Mercer


In case someone faces the similar problem. This is the full solution:

Map step

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

Reduce step

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

Run the command

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

Get the result

db.result.find()
like image 24
masu.mo Avatar answered Nov 14 '22 20:11

masu.mo