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

Mongodb - delete docs from collection that do not have unique value

我收集了这样的对象:

{"_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 方法?

好的,这还没有经过测试,但是你开始吧...这是假设使用 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});
    });
});

我使用这段代码修复了这个问题(这不是此功能的完整代码):

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 变量是您要保留的对象的值,同时删除所有其他重复的且与该值不匹配的对象。查看它,删除其他用户的所有重复项,同时为特定用户保留它们。

这是非常特殊的情况,对于常见问题可能有所不同。但是这个答案的重点是,这段代码可能看起来会吃掉所有的 RAM,但与我迄今为止尝试过的其他实现相比,它不会占用超过 20MB 的 300 万条记录,而且速度很快.

这是我在 mongoDB 中获取重复项的看法。 aggregate 是一个很有帮助的函数。您可以应用多个管道到达您想要的位置。 aggregate

  1. 匹配所有不等于 foo 的用户
  2. 将它们按 value 分组,这将是 _id 并增加在文档集中找到的每个 $_id(原始)的计数。将项目推送到名为 docIds.
  3. 的数组中
  4. 从这个新集合中获取所有 rows/docs 的 $count > 1
  5. 放松(请查看文档以获得更好的解释)

这将为您提供 value 出现不止一次的文档。一旦您对结果集感到满意,您就可以对这些文档执行删除操作。我没有手动 运行 这个...让我们知道..

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