删除重复的数组对象mongodb

时间:2015-04-14 00:02:41

标签: node.js mongodb mongoose duplicates

我有一个数组,并且它包含重复的ID ID,有没有办法删除其中一个重复的数组项?

userName: "abc",
_id: 10239201141,
rounds:
   [{
      "roundId": "foo",
      "money": "123
   },// Keep one of these
   {// Keep one of these
      "roundId": "foo",
      "money": "123
   },
   {
      "roundId": "foo",
      "money": "321 // Not a duplicate.
   }]

我想删除前两个中的一个,并保留第三个,因为ID和钱不会在数组中重复。

提前谢谢!

编辑我发现:

  

db.users.ensureIndex({'rounds.roundId':1,'rounds.money':1},{unique:true,dropDups:true})

这对我没有帮助。有人能帮我吗?我花了好几个小时试图解决这个问题。

问题是,我在两台机器上运行了我的node.js网站,因此两次推送相同的数据。知道这一点,重复数据应该是1索引。我做了一个简单的for循环,可以检测我的情况下是否有重复的数据,我怎么能用mongodb实现这个,所以它删除数组索引的数组对象?

for (var i in data){
    var tempRounds = data[i]['rounds'];
    for (var ii in data[i]['rounds']){
        var currentArrayItem = data[i]['rounds'][ii - 1];
        if (tempRounds[ii - 1]) {
            if (currentArrayItem.roundId == tempRounds[ii - 1].roundId && currentArrayItem.money == tempRounds[ii - 1].money) {
                console.log("Found a match");
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

使用聚合框架计算每个文档的重复数据删除版本:

db.test.aggregate([
    { "$unwind" : "$stats" },
    { "$group" : { "_id" : "$_id", "stats" : { "$addToSet" : "$stats" } } }, // use $first to add in other document fields here
    { "$out" : "some_other_collection_name" }
])

使用$out将结果放入另一个集合中,因为聚合无法更新文档。您可以将db.collection.renameCollectiondropTarget一起使用,将旧版集合替换为新的重复数据删除版本。但是,在废弃旧数据之前,请确保您做的正确。

警告:

1:这不保留stats数组中元素的顺序。如果您需要保留订单,您将从数据库中检索每个文档,手动对数组客户端进行重复数据删除,然后更新数据库中的文档。

2:以下两个对象不会被视为彼此重复:

{ "id" : "foo", "price" : 123 }
{ "price" : 123, "id" : foo" }

如果您认为自己有混合关键订单,请使用$project强制执行$unwind阶段与$group阶段之间的关键顺序:

{ "$project" : { "stats" : { "id_" : "$stats.id", "price_" : "$stats.price" } } }

请务必更改管道其余部分中的id -> id_price -> price_,并将其重命名为最后的idprice,或者将其重命名为另一个$project交换后{1}}。我发现,如果你没有为项目中的字段指定不同的名称,它就不会对它们重新排序,即使密钥顺序在MongoDB中的对象中有意义:

> db.test.drop()
> db.test.insert({ "a" : { "x" : 1, "y" : 2 } })
> db.test.aggregate([
    { "$project" : { "_id" : 0, "a" : { "y" : "$a.y", "x" : "$a.x" } } }
])
{ "a" : { "x" : 1, "y" : 2 } }
> db.test.aggregate([
    { "$project" : { "_id" : 0, "a" : { "y_" : "$a.y", "x_" : "$a.x" } } }
])
{ "a" : { "y_" : 2, "x_" : 1 } }

由于密钥顺序是有意义的,我认为这是一个错误,但它很容易解决。