MongoDb更新旧文档

时间:2018-11-08 05:28:37

标签: mongodb nosql

我是MongoDb和NoSQL存储信息概念的新手。与在SQL Server中不同,在表中添加或更新列名将影响所有记录。我可以假设当我提取记录时,该列将在那里。根据其设置方式,它可能有也可能没有值。

但是在MongoDb中,您将如何处理一个过时的文档,并且想要将其拉出,现在您的代码正在寻找一个不存在或刚被重命名的属性?

1 个答案:

答案 0 :(得分:1)

很少有不同技术的例子。

假设我们有一个集合pets,其文档如下:

{
    kind: "cat",
    age: 2
}

,并且在某个时候我们添加了一个字段“ nick”,因此新文档如下所示:

{
    kind: "cat",
    age: 2,
    nick: "Tom"
}

您的应用需要“昵称”字段才能列出宠物。

  1. 使用默认值

    使用默认值更新旧文档(在SQL术语中您可能将其称为“ ALTER TABLE”魔术):

    db.pets.updateMany({nick: {$exists: false}}, {$set: {nick: "NONAME"}});
    

    如果您需要同时支持这两个版本,则需要在运行时进行。

    在应用程序方面:

    db.pets.find({}).forEach(pet => print(p.nick || "NONAME") );
    

    在数据库方面:

    db.pets.aggregate([
        {$project: {
            kind: 1,
            age: 1,
            nick: { $ifNull: [ "$nick", "NONAME" ] }
        }}
    ])
    
  2. 忽略无效文档

    删除它们:

    db.pets.remove({nick: {$exists: false}})
    

    如果您需要同时支持这两个版本,则需要在运行时将它们过滤掉:

    db.pets.find({
        kind: {$exists: true},
        age: {$exists: true},
        nick: {$exists: true}
    );
    

    您可以通过指定type使其更具防御性:

    db.pets.find({
        kind: {$type: "string"},
        age: {$type: "int"},
        nick: {$type: "string"}
    );
    
  3. 停止程序执行

    db.pets.find({}).forEach(pet => if(!pet.nick){throw new Error("Pet " + pet._id + " has no nick!")} );