我想更新 MongoDB 中包含对象的文档。由于更新的对象是由用户给出的,我不知道他到底要改变什么。
例如,我在用户集合中有此文档:
{
_id: 1,
date: new Date(),
info: {
first_name: "a",
last_name: "b",
phone: "c"
}
}
Run Code Online (Sandbox Code Playgroud)
用户可以编辑名字和姓氏,但不能编辑电话。
这是req.body(我从用户那里收到的输入):
{
info: {
first_name: "aa"
}
}
Run Code Online (Sandbox Code Playgroud)
现在,为了仅更新“info.first_name”并保留存储在 info ojbect 中的其他字段,我必须设置一个更新查询,如下所示:
db.users.update({}, {$set: {"info.first_name": req.body.info.first_name}}, cb);
Run Code Online (Sandbox Code Playgroud)
但输入可以是动态且可变的。我不知道是否总是更新的名字,它可以是姓氏,甚至是其他子对象,例如地址:“info.address.city”(例如)
因此,我像这样处理这些更新:
$set: req.body
Run Code Online (Sandbox Code Playgroud)
就是这样。它有效,但我对此有疑问。它替换了整个信息对象,并且不保留存储在其中的其他密钥 - 电话被删除,姓氏被删除。
有没有办法告诉 MongoDB 不要替换整个对象,而只是更新那些提到的键?
我也研究过它,你不能将 mongo 设置为仅更新特定字段。您可以做的是根据输入动态构建查询。
我通常循环遍历输入,然后验证允许修改的内容,并基于此构建动态查询:
var updateQuery = {};
for(key of req.body.info) {
if (req.body.info.hasOwnProperty(key) && canBeModified(key)) //this would be a function to validate what can be updated
updateQuery['info.' + key] = req.body.info[key]};
}
db.users.update({}, {$set: updateQuery}, cb);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8979 次 |
| 最近记录: |