删除重复的数组对象 mongodb

Remove duplicate array objects mongodb

我有一个数组,它在两个 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 和 money 在数组中不重复。

提前致谢!

我发现的编辑:

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");
            }
        }
    }
}

使用聚合框架计算每个文档的去重版本:

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。我发现,如果您不为项目中的字段指定不同的名称,它不会对它们重新排序,即使键顺序在 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 } }

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