使用map/reduce mongodb进行聚合
我有分层组织的数据,我希望在单个mongodb映射/减少操作中计算多个级别的聚合。有办法做到这一点吗 例如:使用map/reduce mongodb进行聚合,mongodb,mapreduce,Mongodb,Mapreduce,我有分层组织的数据,我希望在单个mongodb映射/减少操作中计算多个级别的聚合。有办法做到这一点吗 例如: { street: "A", district: "1", city: "Z", nb_users: 1 } { street: "A", district: "1", city: "Z", nb_users: 2 } { street: "B", district: "1", city: "Z", nb_users: 3 } { street: "B", district: "1",
{ street: "A", district: "1", city: "Z", nb_users: 1 }
{ street: "A", district: "1", city: "Z", nb_users: 2 }
{ street: "B", district: "1", city: "Z", nb_users: 3 }
{ street: "B", district: "1", city: "Z", nb_users: 2 }
{ street: "C", district: "1", city: "Z", nb_users: 4 }
{ street: "C", district: "1", city: "Z", nb_users: 3 }
{ street: "A", district: "2", city: "Z", nb_users: 5 }
{ street: "B", district: "2", city: "Z", nb_users: 6 }
{ street: "B", district: "2", city: "Z", nb_users: 3 }
结果:
{ street: "A", district: "1", city: "Z", nb_users_street: 3, nb_users_district: 15, nb_users_city: 29 }
{ street: "B", district: "1", city: "Z", nb_users_street: 5, nb_users_district: 15, nb_users_city: 29 }
{ street: "C", district: "1", city: "Z", nb_users_street: 7, nb_users_district: 15, nb_users_city: 29 }
{ street: "A", district: "2", city: "Z", nb_users_street: 5, nb_users_district: 14, nb_users_city: 29 }
{ street: "B", district: "2", city: "Z", nb_users_street: 9, nb_users_district: 14, nb_users_city: 29 }
谢谢你的帮助 不,没有简单的方法可以做到这一点 由于您希望按街道、地区和城市进行聚合,因此需要将它们全部用作发射对象的关键帧的一部分,因此您的贴图功能很可能如下所示:
function(){
emit (
{ street : this.street, district : this.district, city : this.city },
{nb_users : this.nb_users }
);
}
由于“减少”功能仅将记录与匹配的关键字组合在一起,因此您只能将街道、地区和城市都相同的记录组合在一起,这意味着您将无法从这些跨越多条街道的发射对象计算地区或城市的总数
将三个单独的map/reduces转换为三个单独的输出集合将使代码更简单、更易于理解,还将消除在每个街道级别行中重复使用nb_users_district和nb_users_city的冗余
事实上,这三个单独的map/reduce函数非常简单,您应该能够使用MongoDB的内置组函数,我相信它比标准的map/reduce提供了一些性能优势 MongoDB 2.2将引入一个新的聚合框架,该框架将更快,也许能够更好地处理这种情况。然而,我同意Russell的观点,从长远来看,使用3 m/r将非常简单。如果您想将最终文档调整为下面这样的内容,您可以在一个m/r中完成,但是代码会变得非常复杂。但是,它的好处是更像文档
result: {
city: "Z",
nb_users: 29
districts: {
"1": {
nb_users: 15,
streets: {
"A": 3,
"B": 5,
"C": 7
}
},
"2" : {
nb_users: 14,
streets: {
"A": 5,
"B": 9
}
}
}
}
太糟糕了,我现在使用的代码实际上使用了三个连续的map/reduce操作和一个合并操作:按城市/地区/街道聚合,然后按城市/地区聚合这些结果,然后再次仅按城市聚合,最后将聚合结果与原始数据合并。谢谢你的帮助!嗨,克雷格,谢谢你的信息。找到它: