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

时间:2014-01-19 00:05:41

标签: mongodb

我在Mongo有两个收藏:

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

db.authority.find():
{
  "_id": { "$oid" : "52daf174a2cb2f62aed63af3" },
  "name": "Sample Authority"
}

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

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

我试过这个:

db.user.find(
    { 
      $where: function() { 
        db.authority.find({ _id: this.authority_id }).count() == 0  
      }
     })

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

3 个答案:

答案 0 :(得分:2)

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

db.user.find().forEach( function(myDoc) {
    var cursor = db.authority.find({'_id' : myDoc.authority_id});
    if(cursor.hasNext() == false) {
        db.user.remove({_id : myDoc._id});
    }
});

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

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

但你可以试试map reduce: http://cookbook.mongodb.org/patterns/pivot/

我会亲自在代码中执行此操作,但您可能有不同的要求。