gpt4 book ai didi

javascript - MongoDB 更新对象,项目删除未保存

转载 作者:太空宇宙 更新时间:2023-11-04 00:51:17 25 4
gpt4 key购买 nike

我正在使用Angular Fullstack对于网络应用程序。

我通过 $http.post() 我的对象发布我的数据:

{ title: "Some title", tags: ["tag1", "tag2", "tag3"] }

当我编辑对象并尝试 $http.put() 例如:

{ title: "Some title", tags: ["tag1"] }

在控制台中,我得到 HTTP PUT 200 但当我刷新页面时,我仍然收到带有所有 3 个标签的对象。

这就是我在 MongoDB 中保存的方式:

exports.update = function(req, res) {
if (req.body._id) {
delete req.body._id;
}

Question.findByIdAsync(req.params.id)
.then(handleEntityNotFound(res))
.then(saveUpdates(req.body))
.then(responseWithResult(res))
.catch(handleError(res));
};


function saveUpdates(updates) {

return function(entity) {

var data = _.merge(entity.toJSON(), updates);
var updated = _.extend(entity, data);

return updated.saveAsync()
.spread(function(updated) {
return updated;
});
};
}

有人可以解释如何保存已删除项目的对象吗?

我做错了什么?

最佳答案

在客户端(意味着你的nodejs客户端到数据库而不是浏览器)检索代码后使用诸如_.merge_.extend之类的东西是非常糟糕的做法数据库。另外值得注意的是 _.merge 是这里的问题,因为它不会“拿走”东西,而是“增强”您提供的信息已经存在的东西。这不是您想要的,但还有更好的方法。

您应该简单地使用“原子运算符”,例如 $set改为执行此操作:

Question.findByIdAndUpdateAsync(
req.params.id,
{ "$set": { "tags": req.body.tags } },
{ "new": true }
)
.then(function(result) {
// deal with returned result
});

您还确实应该以端点为目标,而不是编写“通用”对象。因此,上面的内容将专门针对相关“标签”的“PUT”,而不会触及对象中的其他字段。

如果您确实必须向其抛出整个对象并期望所有内容进行更新,则使用助手来正确修复更新语句:

function dotNotate(obj,target,prefix) {
target = target || {},
prefix = prefix || "";

Object.keys(obj).forEach(function(key) {
if ( typeof(obj[key]) === "object" ) {
dotNotate(obj[key],target,prefix + key + ".");
} else {
return target[prefix + key] = obj[key];
}
});

return target;
}

var update = { "$set": dotNotate(req.body) };

Question.findByIdAndUpdateAsync(
req.params.id,
update,
{ "new": true }
)
.then(function(result) {
// deal with returned result
});

无论你向它扔什么对象,它都会正确地构造。

尽管在这种情况下,可能直接就足够了:

Question.findByIdAndUpdateAsync(
req.params.id,
{ "$set": req.body },
{ "new": true }
)
.then(function(result) {
// deal with returned result
});

还有其他使用原子运算符的方法,您也可以将它们纳入您的处理逻辑中。但最好考虑对每个元素执行这些操作,至少将根文档属性和数组等内容单独视为子元素。

所有原子操作都与“在数据库中”和“按修改时的状态”的文档交互。从数据库中提取数据,修改它,然后保存回来并不能保证数据尚未更改,并且您可能会覆盖已经提交的其他更改。

我说实话,您的“浏览器客户端”应该知道“标签”数组具有其他两个条目,然后您的“修改请求”应该只是 $pull要从数组中删除的条目,如下所示:

Question.findByIdAndUpdateAsync(
req.params.id,
{ "$pull": { "tags": { "$in": ["tag2", "tag3"] } } },
{ "new": true }
)
.then(function(result) {
// deal with returned result
});

然后,“无论”修改时服务器上文档的当前状态如何,这些更改将是唯一进行的更改。因此,如果在添加的“tag4”处修改了其他内容,并且客户端在发送修改之前尚未收到此类更改的通知,则返回响应也将包含该内容,并且一切都会同步。

了解 update modifiers MongoDB,因为它们将为您提供良好的服务。

关于javascript - MongoDB 更新对象,项目删除未保存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32308892/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com