【问题标题】:Is the order of the MongoDb update operators guaranteed with the Node.Js native driver?Node.Js 原生驱动是否保证 MongoDb 更新操作符的顺序?
【发布时间】:2014-07-01 00:46:46
【问题描述】:

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

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

是否保证$unset 会先执行,$set 会后执行?考虑到理论上不应该依赖于 javascript 对象的键顺序。这也假设 MongoDb 本身保证更新操作符的顺序(为此我已经问过this question

【问题讨论】:

    标签: node.js mongodb mongodb-query


    【解决方案1】:

    不,这些操作没有顺序。事实上,如果你尝试告诉你不能用相同的路径修改同一语句中的项目,你会得到一些错误。所以你不能在同一个更新语句中$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`
    });
    

    所以这实际上不是一个操作,而是有序的操作将它带到尽可能接近服务器的单次往返行程中。

    【讨论】:

      【解决方案2】:

      您不能使用多个更新运算符来定位同一字段,但在这种情况下,您不需要这样做,因为您可以使用单个 $set 替换整个 gp 字段:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-12
        • 1970-01-01
        相关资源
        最近更新 更多