mongodb计数并删除重复值

时间:2014-06-04 13:18:03

标签: mongodb count mapreduce distinct aggregation-framework

我有一个很大的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和聚合框架,但他们从不输出完整的文档,只进行一次完整收集计算

将新数据保存到新集合

会很好

2 个答案:

答案 0 :(得分:1)

如果你使用mongodb 2.6,这里有一个聚合框架的例子:

db.duplicate.aggregate({$group:{_id:"$val",count:{$sum :1}}},
                       {$project:{_id:0, val:"$_id", count:1}},
                       {$out:"deduplicate"})
  1. 包含val和计数

  2. 的群组
  3. 项目重命名_id字段和掩码_id字段

  4. 写入新集合(此处名称为重复数据删除)

  5. 希望它适合你的情况。

答案 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之上减少它,并且您会增加计数。

可能会派上用场吗?