Mongodb - 从集合中删除没有唯一值的文档

时间:2017-03-15 01:08:41

标签: javascript mongodb mongo-shell

我有这样的对象集合:

{"_id":"...", "user":"foo", "value":"a"}, // this one stays coz its user is foo
{"_id":"...", "user":"bar", "value":"a"}, // remove this one
{"_id":"...", "user":"baz", "value":"a"}, // remove this one
{"_id":"...", "user":"qux", "value":"b"}, // this one has unique value so it doesn't get deleted

我想找到并删除所有具有重复值的对象,除非用户是foo

是否有JS mongoshell方法?

3 个答案:

答案 0 :(得分:0)

好的,这个没有经过测试但是在这里你去...这是假设使用Mongoose与数据库进行交互......

let values = [];
let deleteIds = [];

myModel.find({}).then(docs => {
    docs.forEach(d => {
        if (values.indexOf(d.value)) {
            deleteIds.push(d._id);
        } else {
            values.push(d.value);
        }
    })

    deleteIds.forEach(id => {
        myModel.findOneAndRemove({_id: id});
    });
});

答案 1 :(得分:0)

我通过使用这段代码解决了这个问题(这不是此功能的完整代码):

let query = {
  user:targetedUser
}
let projection = {
  _id:0, id:1, user:1
}


collection.find(query, projection)
      .on('data', doc => {
        collection.deleteMany({id:doc.id, user: {$not: new RegExp(targetedUser)}})
      })
      .on('end', _=> {
        db.close()
      })

基本上targetedUser变量是您想要保留的对象的值,同时删除所有其他重复且与该值不匹配的对象。查看它,从其他用户删除所有重复项,同时保留特定用户。

这是非常具体的情况,对于通常的问题可能会有所不同。但这个答案的重点在于,这段代码看起来可能会占用所有内存,但300万条记录的内存不超过20MB,而且与我迄今为止尝试过的其他实现相比,速度也快。

答案 2 :(得分:0)

这是我在mongoDB中获取重复项的看法。 aggregate是有用的功能。您可以应用多个管道来到达您想要的位置。 aggregate

  1. 匹配所有不等于foo的用户
  2. value对它们进行分组,这将是_id并增加文档集中找到的每个$_id(原始)的计数。将项目推送到名为docIds
  3. 的数组中
  4. 从这个新集中获取所有包含$ count>的行/文档1
  5. 放松(请查看文档以获得更好的解释)
  6. 这将为您提供value多次出现的文档。一旦您对结果集感到满意,就可以对这些文档执行删除操作。我没有手动运行这个......让我们知道..

    db.collection.aggregate([{
                $match: {
                    "user": {
                        $ne: "foo"
                    }
                }
            }, {
                $group: {
                    _id: "$value",
                    docIds: {
                        $push: "$_id"
                    },
                    count: {
                        $sum: 1
                    }
                }
            }, {
                $match: "$count": {
                    $gt: 1
                }
            }, {
                $unwind: $docIds
            }
        ])