当前位置:Gxlcms > 数据库问题 > 使用aggregate在MongoDB中查找重复的数据记录

使用aggregate在MongoDB中查找重复的数据记录

时间:2021-07-01 10:21:17 帮助过:38人阅读

mongoose = require(‘mongoose‘); var Schema = mongoose.Schema; var customerSchema = new mongoose.Schema({ cname: String, cellPhone, String, sender: String, tag: String, behaviour: Number, createTime: { type: Date, default: Date.now }, current:{ type: Boolean, default: true } }, { versionKey: false }); customerSchema.index({cname:1,cellPhone:1,sender:1,tag:1,behaviour:1}, {unique: true});

module.exports = mongoose.model(‘customer‘, customerSchema);

  上面的model中我们定义了表customer的结构,并通过index()方法在字段cname,cellPhone,sender,tag,behaviour上创建了唯一索引,这样当包含这些字段的重复数据被插入时,数据库会抛出异常。借用mongoose,如果数据库表之前已经被创建并且程序正在运行中,当我们修改model并添加索引,然后重新启动app,只要有对该model的访问,mongoose会自动进行检测并创建索引。当然,如果数据出现重复,则索引创建会失败。此时我们可以通过在创建索引时添加dropDups选项,让数据库自动将重复的数据删除,如:

customerSchema.index({cname:1,cellPhone:1,sender:1,tag:1,behaviour:1}, {unique: true, dropDups: true});

  不过据MongoDB的官方说明,自3.0以后的版本不再使用该选项,而且也并没有提供替代的解决办法。貌似官方不再提供创建索引时自动删除重复记录的功能。那如何才能快速有效地找出重复的记录并且删除呢?首先我们要找出这些记录,然后通过remove()方法进行删除。下面的查询语句可以找出给定字段有重复数据的记录:

db.collection.aggregate([
  { $group: { 
    _id: { firstField: "$firstField", secondField: "$secondField" }, 
    uniqueIds: { $addToSet: "$_id" },
    count: { $sum: 1 } 
  }}, 
  { $match: { 
    count: { $gt: 1 } 
  }}
])

  替换_id属性的值以指定你想要进行判断的字段。相应地,在Node.js中代码如下:

var deferred = Q.defer();
var group = { firstField: "$firstField", secondField: "$secondField"};

model.aggregate().group({
    _id: group,
    uniqueIds: {$addToSet: ‘$_id‘},
    count: {$sum: 1}
}).match({ count: {$gt: 1}}).exec(deferred.makeNodeResolver());

return deferred.promise;

  上述代码使用了Q来替换函数执行中的回调。在Node.js的异步编程中,使用Q来处理回调是个不错的选择。

  下面是返回的结果:

/* 1 */
{
    "result" : [ 
        {
            "_id" : {
                "cellPhone" : "15827577345",
                "actId" : ObjectId("5694565fa50fea7705f01789")
            },
            "uniqueIds" : [ 
                ObjectId("569b5d03b3d206f709f97685"), 
                ObjectId("569b5d01b3d206f709f97684")
            ],
            "count" : 2.0000000000000000
        }, 
        {
            "_id" : {
                "cellPhone" : "18171282716",
                "actId" : ObjectId("566b0d8dc02f61ae18e68e48")
            },
            "uniqueIds" : [ 
                ObjectId("566d16e6cf86d12d1abcee8b"), 
                ObjectId("566d16e6cf86d12d1abcee8a")
            ],
            "count" : 2.0000000000000000
        }
    ],
    "ok" : 1.0000000000000000
}

  从结果中可以看到,一共有两组数据相同的记录,所以返回的result数组的长度为2。uniqueIds属性为一个数组,其中存放了重复记录的_id字段的值,通过该值我们可以使用remove()方法来查找并删除对应的数据。

 

使用aggregate在MongoDB中查找重复的数据记录

标签:

人气教程排行