Mongoose update() 真正更新了啥?
Posted
技术标签:
【中文标题】Mongoose update() 真正更新了啥?【英文标题】:What does Mongoose update() really update?Mongoose update() 真正更新了什么? 【发布时间】:2017-02-12 08:30:34 【问题描述】:Mongoose 文档mention 这个示例代码:
Tank.findById(id, function (err, tank)
if (err) return handleError(err);
tank.size = 'large';
tank.save(function (err, updatedTank)
if (err) return handleError(err);
res.send(updatedTank);
);
);
这是否会导致 MongoDB update() 命令仅设置 size
属性(即 db.tanks.update(_id: tank._id, $set: size: "large");
),还是会替换整个文档?
或者,换句话说,如果另一个客户端在findById()
返回之后但在save()
执行之前更新另一个属性(比如color
)怎么办? color
是恢复到之前的值还是保持原样?
而且,如果 Mongoose 足够聪明,可以只更新“已更改”的属性,那么究竟是如何检测到的(在之前/之后比较值?还是通过 tank
对象上的设置器?)?如果坦克size
已经“大”了怎么办?
我问这个问题是因为 Mongoose docs 对此不是很清楚,我想了解 Mongoose 是如何设计和 打算在此使用尊重。
【问题讨论】:
自己测试应该比较容易。 如果我没有要测试的数据库,则不会。此外,测试并不能准确地揭示一个库应该做什么。糟糕的测试可能会导致错误的假设。 我怀疑除了 Mongoose 的开发人员之外,您是否会从任何人那里得到关于应该发生的确切答案,尤其是因为文档不是确定的。普通用户在此处发布的答案将是轶事。 【参考方案1】:一些测试表明,Mongoose 跟踪对文档的修改(通过使用设置器,正如您已经提到的),并将运行 $set
的新值的更新。
所以这个:
tank.size = 'large';
tank.save(...);
(粗略地说)实现为:
tankCollection.update( _id : tank._id , $set : size : 'large' , ...);
如果size
之前的值也是large
,则不会执行更新。此外,如果文档是新的,它将运行不同的代码路径(调用 tankCollection.insert()
)。
所以并发更新应该可以工作,前提是它们不更新相同的属性(在这种情况下,最后执行的更新获胜)。
【讨论】:
以上是关于Mongoose update() 真正更新了啥?的主要内容,如果未能解决你的问题,请参考以下文章
mongoose Model.update() - 只更新提供的值
使用 mongoose 通过 update 方法向 mongodb 中的现有文档添加新字段