如何删除MongoDB中引用损坏的文档?

rom*_*nsh 5 mongodb

我在 Mongo 中有两个集合:

db.user.find():
{
  "_id": { "$oid" : "52db05e6a2cb2f36afd63c47" },
  "name": "John",
  "authority_id": { "$oid" : "52daf174a2cb2f62aed63af3" },
}
{
  "_id": { "$oid" : "52db05e6a2cb2f36afd63d00" },
  "name": "Joe",
  "authority_id": { "$oid" : "52daf174a2cb2f62aed63af3" },
}
Run Code Online (Sandbox Code Playgroud)

db.authority.find():
{
  "_id": { "$oid" : "52daf174a2cb2f62aed63af3" },
  "name": "Sample Authority"
}
Run Code Online (Sandbox Code Playgroud)

用户通过 ObjectId 存储对授权 ID 的引用。

现在我的问题:多个权限已被删除,不再收集。如果他们的 authority_id 指向已删除的权限,我需要找到一种方法来遍历“用户”集合并删除它们。

我试过这个:

db.user.find(
    { 
      $where: function() { 
        db.authority.find({ _id: this.authority_id }).count() == 0  
      }
     })
Run Code Online (Sandbox Code Playgroud)

但是在那里无法访问“db”。是否可以在迭代中实现引用检查?

Rui*_*tro 7

您可以使用聚合来查找所有孤立用户,然后将其删除。

const orphanUsers = db.user.aggregate([
    {
      // Join authority collection using authority_id
      $lookup: {
        from: "authority",
        localField: "authority_id",
        foreignField: "_id",
        as: "authority"
      }
    },
    // filter users without authority (means authority_id doesn't exist)
    { $match: { authority: [] } },
    // return only the _id
    { $project: { _id: "$_id" } }
])

// Delete all orphan users
db.user.deleteMany({
    _id: { $in: orphanUsers.map(({ _id }) => _id) }
})
Run Code Online (Sandbox Code Playgroud)


Par*_*ade 5

您可以通过在 javascript shell 上迭代光标或使用任何 Mongo 驱动程序来删除损坏的条目。以下示例将为您提供在 javascript shell 上执行此操作的想法。

db.user.find().forEach((user) => {
    const authority = db.authority.findOne({'_id' : user.authority_id});

    if(!authority) db.user.remove({_id : user._id});
});
Run Code Online (Sandbox Code Playgroud)

  • 请不要执行`cursor.hasNext() == false`。使用 `!cursor.hasNext()` 代替,或者,如果您需要严格检查 `false`,请使用 `===` 并且可能将 `false` *放在第一位*,以便更清晰 (3认同)

yǝs*_*ǝla 0

根据http://docs.mongodb.org/manual/reference/operator/query/where/,“$where 运算符表达式无法访问 mongo shell 中可用的某些全局函数或属性,例如 db” 。

但你可以尝试映射减少: http: //cookbook.mongodb.org/patterns/pivot/

我个人会用代码来完成它,但您可能有不同的要求。