Node.js原生驱动程序中,MongoDb更新运算符的顺序是否有保证?

3

考虑使用 Node.JS 驱动程序执行以下 MongoDb 更新操作:

collection.update({ /* query */}, { $unset: { 'gp': 1 }, $set: { 'gp.status': 'AB' }}, function(err) {
    // ...
})

是否有保证$unset将首先执行,然后才会执行$set?考虑到理论上不应该依赖javascript对象键的顺序。这也假设MongoDb本身保证更新操作符的顺序(对此我已经提出了这个问题)。

2个回答

6
不,这些操作没有顺序。事实上,如果你尝试这样做,你会得到一些错误提示,告诉你不能在同一语句中使用相同路径修改项。因此,你不能在同一更新语句中$unset$set,因为两者都试图对“gp”进行操作。
如果你的 MongoDB 版本是 2.6 或更高版本,则可以使用“批量更新”操作,尽可能地实现原子更新并保证顺序。
var bulk = collection.initializeOrderedBulkOp();
bulk.find({ /* query */}).updateOne({ "$unset": { "gp": 1 } });
bulk.find({ /* query */}).updateOne({ "$set": { "gp.status": "AB" } });
bulk.execute(function(err,result) {
  // Write concern result for two ops in `result`
});

因此,这实际上不是一个操作,但有序操作使其尽可能地接近通过单次往返到服务器实现。


3

您不能像那样使用多个更新操作符来目标同一个字段,但在这种情况下,您不需要这样做,因为您可以使用单个$set来替换整个gp字段:

collection.update({ /* query */}, {$set: {gp: {status: 'AB'}}, function(err) {
    // ...
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接