我正在尝试使用 map-reduce 来了解这何时有用。
所以我有一个名为“actions”的集合,其中包含 10 万个这样的文档:
{
"profile_id":1111,
"action_id":2222
}
现在我正在尝试做 map-reduce 示例。我正在尝试获取“所有用户和每个用户的总操作数” 的列表。这可能吗?我的代码:
db.fbooklikes.mapReduce(
function(){
emit(this.profile_id, this.action_id);
},
function(keyProfile, valueAction){
return Array.sum(valueAction);
},
{
out:"example"
}
)
.. 这是行不通的。结果是:
"counts" : {
"input" : 100000,
"emit" : 100000,
"reduce" : 1146,
"output" : 13
},
"ok" : 1,
"_o" : {
"result" : "map_reduce_example",
"timeMillis" : 2539,
"counts" : {
"input" : 100000,
"emit" : 100000,
"reduce" : 1146,
"output" : 13
},
"ok" : 1
},
我正在尝试做的是 map-reduce 可能实现的事情吗?
最佳答案
是的,您可以使用它,但更精确的回答是可能有更好的工具来完成您想要的事情。
MapReduce 对于某些任务很方便,但通常最适合其他任务不适用的情况。在 MongoDB 中包含 mapReduce 早于 aggregation framework 的引入,这通常是您应该尽可能使用的:
db.fbooklikes.aggregate([
{ "$group": {
"_id": "$profile_id",
"count": { "$sum": 1 }
}}
])
这将简单地返回按“profile_id”的每个值分组的集合中所有文档的计数。
MapReduce 需要 JavaScript 评估,因此运行速度比聚合框架实现的 native 代码功能慢得多。有时你必须使用它,但在简单的情况下最好不要使用它,并且有一些怪癖你需要了解:
db.fbooklikes.mapReduce(
function(){
emit(this.profile_id, 1);
},
function(key,values){
return Array.sum(values);
},
{
out: { "inline": 1 }
}
)
人们对 mapReduce 最怀念的一点是,reducer 几乎从不为每个发出的键只调用一次。事实上,它将以“ block ”的形式处理输出,从而“减少”该输出的一部分并将其放回以针对其他输出再次“减少”,直到该键只有一个值。
因此,从 reduce 函数发出与从“map”函数发送的相同类型的数据非常重要。这是一个棘手的问题,当您不了解该功能的那部分时,可能会导致奇怪的结果。这实际上是 mapReduce 可以处理单个键值的大量结果并减少它们的底层方式。
但一般来说,您应该尽可能使用聚合框架,如果问题需要一些特殊的计算,而这些计算在那里是不可能的,或者有一些复杂的文档遍历,您需要使用 JavaScript 检查,那就是你在哪里使用 mapReduce。
关于javascript - mongodb - 不明白为什么/如何使用 map-reduce,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25985315/