我有一个很大的mongodb集合,有很多像这样的重复插入
{ "_id" : 1, "val" : "222222", "val2" : "37"}
{ "_id" : 2, "val" : "222222", "val2" : "37" }
{ "_id" : 3, "val" : "222222", "val2" : "37" }
{ "_id" : 4, "val" : "333333", "val2" : "66" }
{ "_id" : 5, "val" : "111111", "val2" : "22" }
{ "_id" : 6, "val" : "111111", "val2" : "22" }
{ "_id" : 7, "val" : "111111", "val2" : "22" }
{ "_id" : 8, "val" : "111111", "val2" : "22" }
我想计算每个插入的所有重复项,并且只在DB中留下一个带有计数编号的唯一条目
{ "_id" : 1, "val" : "222222", "val2" : "37", "count" : "3"}
{ "_id" : 2, "val" : "333333", "val2" : "66", "count" : "1"}
{ "_id" : 2, "val" : "111111", "val2" : "22", "count" : "4" }
我已经检查了MapReduce和聚合框架,但他们从不输出完整的文档,只进行一次完整收集计算
将新数据保存到新集合
会很好答案 0 :(得分:1)
如果你使用mongodb 2.6,这里有一个聚合框架的例子:
db.duplicate.aggregate({$group:{_id:"$val",count:{$sum :1}}},
{$project:{_id:0, val:"$_id", count:1}},
{$out:"deduplicate"})
包含val
和计数
项目重命名_id字段和掩码_id字段
写入新集合(此处名称为重复数据删除)
希望它适合你的情况。
答案 1 :(得分:0)
使用增量地图缩小可能会更容易
mapper=function(){
emit({'val1':this.val, 'val2':this.val2}, {'count':1});
}
reducer=function(k,v){
counter=0;
for (i=0;i<v.length;i++){
counter+=v[i].count;
}
return {'count':counter}
}
然后在shell中你需要做
bigcollection.map_reduce(mapper, reducer, {out:{reduce:'reducedcollection'}})
这应该会产生一个名为简化集合的新集合。您的值将是ID,计数将在那里。请注意在新集合中使用两个值作为键。如果您想查找特定实例,可以执行以下操作:
reducedcollection.findOne({'id.val1':'33333', 'id.val2':'22'})
有趣的是,您现在可以删除旧的集合,并且随着新数据的进入,map会在reducecollection之上减少它,并且您会增加计数。
可能会派上用场吗?