I have a map reduce function that works on a collection as follows:
function Map() {
emit (
this.name,
{
count : 1,
flag : this.flag
}
);
}
function Reduce(key, values) {
var count = 0;
var flag = false;
for (var i in values){
count = count + 1;
if (i.flag)
flag = true;
}
var reduced = {
count : count,
flag : flag
}
return reduced;
}
function Finalize(key, reduced) {
if (reduced.count>10 || reduced.flag){
var finalized = {
"count" : reduced.count
}
return reduced;
}
return null;
}
What I am trying to do is that the Finalize will only return objects that pass a certain threshold (e.g. count>10). Currently it is still returning objects and the count is just null.
Any ideas?
I would suggest you use the aggregation framework instead as it's much faster and easier to understand. Your above M/R/F can be written as easily as:
db.so.insert( { name: "Derick" } );
db.so.insert( { name: "Derick" } );
db.so.insert( { name: "Derick" } );
db.so.insert( { name: "Derick" } );
db.so.insert( { name: "Checklist" } );
db.so.insert( { name: "Checklist" } );
db.so.insert( { name: "Whoop" } );
db.so.insert( { name: "Whoop", flagged: true } );
db.so.aggregate( [
{ $group: {
_id: '$name',
count: { $sum: 1 },
flagged: { $sum:
{ $cond: [ { $eq: [ '$flagged', true ] }, 1, 0 ] }
}
} },
{ $match: { $or: [ { count: { $gt: 3 } }, { flagged: { $gt: 0 } } ] } }
] );
Which returns:
{
"result" : [
{
"_id" : "Whoop",
"count" : 2,
"flagged" : 1
},
{
"_id" : "Derick",
"count" : 4,
"flagged" : 0
}
],
"ok" : 1
}
You can't.
Finalize will can only change the format of your value, but you cannot cancel out the key (which is actually dictated by the map phase emits).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With