【问题标题】:MongoDB: Update a string field in all documentsMongoDB:更新所有文档中的字符串字段
【发布时间】:2016-09-26 01:36:32
【问题描述】:

我有一个 MongoDB 数据库,其中包含许多文档。每篇文章都有一个名为myField 的字段,其中包含一个字符串。

我是否可以对集合中的所有个文档运行批量更新,为每个文档修改myField 的值?

在我的例子中,我只想从每个字段中去掉一个尾随的“.html”。我在我的应用程序中使用 node.js 与 Mongo 进行交互,但如果可能的话,我希望能够在 mongo 命令提示符上运行单个命令来执行此更新。

【问题讨论】:

    标签: javascript node.js mongodb database


    【解决方案1】:

    是的,可以使用 mongo 从命令提示符更新 mongoDB 文档信息。

    说出脚本文件名migration.js 并转到此文件目录并打开命令提示符并运行此命令。

    mongo localhost/dbName migration.js
    

    migration.js 类似代码:

    print('Please wait it may will take some time to complete migration');
    print('....');
    
    db.collectionName.find().forEach( function(doc) {
    
        if(!doc._id) {
            print('No doc found');
            return;
        }
        // if need can apply logic to update myField
    
        db.collectionName.update({_id: doc._id}, {$set: {myField: "newVale"}});
    });
    
    print('Migration has been completed :)');
    

    【讨论】:

      【解决方案2】:

      考虑使用 bulkWrite API 来利用更新,因为它比在循环中进行更新更好、更有效地处理这一点,即每次迭代发送每个更新请求可能会很慢数据集。

      bulkWrite API 以 500 次为单位将写入发送到服务器,这可以为您提供更好的性能,因为您不会将每个请求都发送到服务器,而是每 500 个请求发送一次。

      对于批量操作,MongoDB 对每个批次强制执行 default internal limit of 1000 操作,因此从某种意义上说,选择 500 个文档会很好,因为您可以对批次大小进行一些控制,而不是让 MongoDB 强制执行默认值,即对于较大的操作> 1000 个文档的大小。

      举个例子:

      var bulkUpdateOps = [], // create an array to hold the update operations
          counter = 0, // counter to control the batch sizes
          rgx = /\.(html)$/i, // regex for querying and updating the field
          cursor = db.collection.find({ "myField": rgx }); // cursor for iterating
      
      cursor.snapshot().forEach(function(doc) {
          var updatedField = doc.myField.replace(rgx, ''); // update field
          bulkUpdateOps.push({ // queue the update operations to an array
              "updateOne": {
                  "filter": { 
                      "_id": doc._id, 
                      "myField": { "$ne": updatedField } 
                  },
                  "update": { "$set": { "myField": updatedField } }
              }
          });
          counter++;
      
          if (counter % 500 == 0) { // send the update ops in bulk
              db.collection.bulkWrite(bulkUpdateOps);
              bulkUpdateOps = []; // reset the array
          }
      })
      
      if (counter % 500 != 0) { // clean up remaining operations in the queue
          db.collection.bulkWrite(bulkUpdateOps)
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-20
        • 2021-07-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-28
        • 2020-07-04
        相关资源
        最近更新 更多