我是MongoDb和NoSQL存储信息概念的新手。与在SQL Server中不同,在表中添加或更新列名将影响所有记录。我可以假设当我提取记录时,该列将在那里。根据其设置方式,它可能有也可能没有值。
但是在MongoDb中,您将如何处理一个过时的文档,并且想要将其拉出,现在您的代码正在寻找一个不存在或刚被重命名的属性?
答案 0 :(得分:1)
很少有不同技术的例子。
假设我们有一个集合pets
,其文档如下:
{
kind: "cat",
age: 2
}
,并且在某个时候我们添加了一个字段“ nick”,因此新文档如下所示:
{
kind: "cat",
age: 2,
nick: "Tom"
}
您的应用需要“昵称”字段才能列出宠物。
使用默认值更新旧文档(在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" ] }
}}
])
删除它们:
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"}
);
db.pets.find({}).forEach(pet => if(!pet.nick){throw new Error("Pet " + pet._id + " has no nick!")} );