masu.mo
masu.mo

Reputation: 793

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?

Upvotes: 5

Views: 7132

Answers (2)

masu.mo
masu.mo

Reputation: 793

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()

Upvotes: 3

Ian Mercer
Ian Mercer

Reputation: 39277

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

Upvotes: 5

Related Questions