我有几个Mongoid模型,我正在运行mapreduce,我想将统一结果存储在一个daily_stats
集合中。我的地图& reduce函数适用于所有3个模型,但即使通过collection.mapreduce(map, reduce, {:out => "daily_stats", :raw => true})
输出,后续map reduce操作的结果也会覆盖以前的结果,即使它们没有重叠键:
{'_id': "2012-06-01", 'values': {photos: 10}}
{'_id': "2012-06-02", 'values': {photos: 10}}
后续传递返回时,photos
的值被抛出:
{'_id': "2012-06-01", 'values': {comments: 1}}
{'_id': "2012-06-02", 'values': {comments: 6}}
我尝试与collection.mapreduce(map, reduce, {:out => {:merge => "daily_stats"}, :raw => true})
合并,但这似乎也不起作用。
有什么想法吗?
更新
地图&对于每个模型,reduce函数都是这样的:
地图:
function() {
day = Date.UTC(this.created_at.getFullYear(), this.created_at.getMonth(), this.created_at.getDate());
emit(day, {users: 1});
};
降低: function(key,values){ var users_added_count = 0;
values.forEach(function(v) {
users_added_count += parseInt(v['users']) || 0;
});
return {users: users_added_count};
}
以下是有关结果架构的一些额外信息:
{ "_id" : 1337040000000,
"value" : {
"apartments" : 280,
"price" : 1003653,
"photos" : 83,
"comments" : 0 }
}
答案 0 :(得分:1)
如果您查看map reduce的MongoDB文档(http://www.mongodb.org/display/DOCS/MapReduce#MapReduce-Outputoptions),您会看到默认情况下,MR输出集合会替换任何现有的具有相同名称的集合。 “合并”将新数据添加到旧输出集合中,但使用相同的密钥覆盖文档。
看起来你的关键是日期?如果
{'_id': "2012-06-01", 'values': {photos: 10}}
和
{'_id': "2012-06-01", 'values': {comments: 1}}
具有相同的密钥,第二个文档将在您运行MR时替换第一个文档。您需要指定一个更独特的键,或者您需要有多个输出集合(可能一个用于照片,一个用于评论?)。
答案 1 :(得分:0)
您可以使用哈希键发射,使其在模型上独一无二p>
emit({day: day, type: '<model class name>'}, 1);