关系型数据库中分组去重一般都是group by … having(count(1)>1)…赛选出来重复的记录组,然后一条sql搞定,但是在mongodb里面,没有这么方便了,需要自己写脚本来实现,可以通过aggregate、group、match来操作处理。1,准备录入测试数据
db.stu.insert({cid:1,age:14,name:"gom1"});db.stu.insert({cid:1,age:12,name:"jack2"});db.stu.insert({cid:2,age:13,name:"Lily3"});db.stu.insert({cid:2,age:14,name:"tony4"});db.stu.insert({cid:2,age:9,name:"Harry5"});db.stu.insert({cid:2,age:13,name:"Vincent6"});db.stu.insert({cid:1,age:14,name:"bill7"});db.stu.insert({cid:2,age:17,name:"tim8"});db.stu.insert({cid:1,age:10,name:"bruce9"});db.stu.insert({cid:3,age:20,name:"luxi10"});执行窗口显示如下:mongos> use test;switched to db testmongos> mongos> db.stu.insert({cid:1,age:14,name:"gom1"});mongos> db.stu.insert({cid:1,age:12,name:"jack2"});mongos> db.stu.insert({cid:2,age:13,name:"Lily3"});mongos> db.stu.insert({cid:2,age:14,name:"tony4"});mongos> db.stu.insert({cid:2,age:9,name:"Harry5"});mongos> db.stu.insert({cid:2,age:13,name:"Vincent6"});mongos> db.stu.insert({cid:1,age:14,name:"bill7"});mongos> db.stu.insert({cid:2,age:17,name:"tim8"});mongos> db.stu.insert({cid:1,age:10,name:"bruce9"});mongos> db.stu.insert({cid:3,age:20,name:"luxi10"});2,开始分组测试,按照cid进行分组
2.1,先统计分组记录数
var group=([
{group:{_id:" cid", max_age: {max:" age"},count: { sum: 1 }}},
{ sort:{count:-1}}
])
执行窗口如下:mongos> var group=([...{$group:{_id:"$cid", max_age: {$max:"$age"},count: { $sum: 1 }}},...{$sort:{count:-1}}... ])mongos>2.2,定义就是找出存在重复的分组,使用管道操作符match,条件是普通查询的格式,但是作用于 group的输出结果的格式:
var match ={“match":{"count" : {" gt” : 1}}};
执行窗口如下:mongos> var match ={"$match":{"count" : {"$gt" : 1}}};mongos>3 获取数据
mongos> db.stu.aggregate(group, match);{"result" : [{"_id" : 2,"max_age" : 17,"count" : 5},{"_id" : 1,"max_age" : 14,"count" : 4},{"_id" : 3,"max_age" : 20,"count" : 1}],"ok" : 1}mongos> PS:这里match无效,出来count为1的数据,没有match成功,问题在哪里呢?
网友Traveller的指点: db.stu.aggregate(group, match); 看出来了吗?你这样调用相当于把match作为options传进去了,当然没有用,这种方法得不到最终的数据,因为每个管道是数组的一个元素,而group单独是一个数组,match是一个元素。除非把它加进数组里面,看如下写法,
group.push(match);
db.stu.aggregate(group);
然后自己去看官网进一步研究: http://docs.mongoing.com/manual-zh/reference/method/db.collection.aggregate.html#db.collection.aggregate,查看了aggregate介绍,aggregate的方法签名是function (pipeline, aggregateOptions),
第一个参数是piplines,所有的对数据的判断条件都应该在这里面。
第二个参数是options,指定查询时候使用的一些选项。
The options document can contain the following fields and values:包括explain、allowDiskUse、cursor,所以我传入的match是针对group的判断条件,所以不能作为第二个参数,而应该放到第一个参数里面去,所以需要用到group的push功能,将match加入第一个参数里面去才能使count>1的判断生效。
4,使用group的push功能
mongos> group.push(match);3mongos> db.stu.aggregate(group);{"result" : [{"_id" : 2,"max_age" : 17,"count" : 5},{"_id" : 1,"max_age" : 14,"count" : 4}],"ok" : 1}mongos> 看到已经过滤掉了count=1的记录组了,表示push成功了。更多MongoDB相关教程见以下内容:CentOS 编译安装 MongoDB与mongoDB的php扩展 http://www.linuxidc.com/Linux/2012-02/53833.htmCentOS 6 使用 yum 安装MongoDB及服务器端配置 http://www.linuxidc.com/Linux/2012-08/68196.htmUbuntu 13.04下安装MongoDB2.4.3 http://www.linuxidc.com/Linux/2013-05/84227.htmMongoDB入门必读(概念与实战并重) http://www.linuxidc.com/Linux/2013-07/87105.htmUbunu 14.04下MongoDB的安装指南 http://www.linuxidc.com/Linux/2014-08/105364.htm《MongoDB 权威指南》(MongoDB: The Definitive Guide)英文文字版[PDF] http://www.linuxidc.com/Linux/2012-07/66735.htmNagios监控MongoDB分片集群服务实战 http://www.linuxidc.com/Linux/2014-10/107826.htm基于CentOS 6.5操作系统搭建MongoDB服务 http://www.linuxidc.com/Linux/2014-11/108900.htm
MongoDB 的详细介绍:请点这里
MongoDB 的下载地址:请点这里
本文永久更新链接地址