Mongodb and MapReduce - results missing
-
21-12-2019 - |
Question
with this code:
var map = function(){
emit(1, { read: this.read, important: this.important, count: 1 })
}
var reduce = function(key, vals) {
var i = 0, r = 0, c = 0;
vals.forEach(function(d) {
r += !d.read ? 0 : 1;
i += d.important ? 0 : 1
c += d.count;
});
return { read: r, important: i, count: c }
}
db.ipdr.mapReduce(map, reduce, { out: "__mr_test", verbose: true, query: { liid: "40001" } });
db.getCollection("__mr_test").find();
I get incomplete count:
{
"_id" : 1,
"value" : {
"read" : 1,
"important" : 7,
"count" : 7607
}
}
"count" is OK, but "read" and "important" should be a lot higher. Am I missing something?
Solution
This is not a good usage of mapReduce. The aggregation framework uses native code which is much faster than JavaScript execution and can do the same job. Assuming "read" and "important" are logical values that is:
db.posts.aggregate([
{ "$sort": { "read": 1, "important": 1 } },
{ "$group": {
"_id": null,
"read": { "$sum": { "$cond": [ "$read", 1, 0 ] } },
"important": { "$sum": { "$cond": [ "$important", 1, 0 ] } },
"count": { "$sum": 1 }
}}
])
So not only faster but much more simple to code.
Given the sample documents:
{ "read" : true, "important" : false }
{ "read" : true, "important" : false }
{ "read" : false, "important" : false }
{ "read" : false, "important" : true }
{ "read" : true, "important" : true }
The result would be:
{ "_id" : null, "read" : 3, "important" : 2, "count" : 5 }
OTHER TIPS
Instead of
r += !d.read ? 0 : 1;
i += d.important ? 0 : 1
c += d.count;
Shouldn't you be having
r += !d.read ? 0 : d.read;
i += d.important ? 0 : 1
c += d.count;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow