【问题标题】:Replace a word from a string替换字符串中的单词
【发布时间】:2015-07-03 22:42:32
【问题描述】:

我有这样一个字段的 mongodb 文档:

Image : http://static14.com/p/Inc.5-Black-Sandals-5131-2713231-7-zoom.jpg

如何将字符串值中的zoom 部分替换为其他文本以获得:

Image : http://static14.com/p/Inc.5-Black-Sandals-5131-2713231-7-product2.jpg

【问题讨论】:

    标签: mongodb replace mongodb-query


    【解决方案1】:

    您可以使用 mongo 的 forEach() 游标方法通过 $set 运算符进行原子更新:

    db.collection.find({}).snapshot().forEach(function(doc) {
        var updated_url = doc.Image.replace('zoom', 'product2');
        db.collection.update(
            {"_id": doc._id}, 
            { "$set": { "Image": updated_url } }
        );
    });
    

    鉴于要更新的​​集合非常大,您可以使用 bulkWrite 稍微加快速度,并将更新操作重组为批量发送:

    var ops = [];
    db.collection.find({}).snapshot().forEach(function(doc) {
        ops.push({
            "updateOne": {
                "filter": { "_id": doc._id },
                "update": { "$set": { "Image": doc.Image.replace('zoom', 'product2') } }
            }
        });
    
        if ( ops.length === 500 ) {
            db.collection.bulkWrite(ops);
            ops = [];
        }
    })
    
    if ( ops.length > 0 )  
        db.collection.bulkWrite(ops);
    

    【讨论】:

      【解决方案2】:
      db.myCollection.update({image: 'http://static14.com/p/Inc.5-Black-Sandals-5131-2713231-7-zoom.jpg'}, {$set: {image : 'http://static14.com/p/Inc.5-Black-Sandals-5131-2713231-7-product2.jpg'}})
      

      如果您需要对多个文档多次执行此操作,则需要使用函数对其进行迭代。见这里:MongoDB: Updating documents using data from the same document

      【讨论】:

      • 有超过 70000 个输入你的解决方案是不可能的
      • 正如我的回答所暗示的那样,您不想手动完成它们就足够了。但问题并没有具体说明需要更改多少文件
      【解决方案3】:

      现在,

      • Mongo 4.2db.collection.updateManydb.collection.update 的别名)开始可以接受聚合管道,最终允许根据自己的值更新字段。
      • Mongo 4.4 开始,新的聚合运算符$replaceOne 可以很容易地替换字符串的一部分。
      // { "Image" : "http://static14.com/p/Inc.5-Black-Sandals-5131-2713231-7-zoom.jpg" }
      // { "Image" : "http://static14.com/p/Inc.5-Black-Sandals-5131-2713231-7-boom.jpg" }
      db.collection.updateMany(
        { "Image": { $regex: /zoom/ } },
        [{
          $set: { "Image": {
            $replaceOne: { input: "$Image", find: "zoom", replacement: "product2" }
          }}
        }]
      )
      // { "Image" : "http://static14.com/p/Inc.5-Black-Sandals-5131-2713231-7-product2.jpg" }
      // { "Image" : "http://static14.com/p/Inc.5-Black-Sandals-5131-2713231-7-boom.jpg" }
      
      • 第一部分 ({ "Image": { $regex: /zoom/ } }) 通过过滤要更新的文档(包含 "zoom" 的文档)来加快查询速度
      • 第二部分($set: { "Image": {...)是更新聚合管道(注意方括号表示使用聚合管道):
        • $set 是一个新的聚合运算符 (Mongo 4.2),在这种情况下会替换字段的值。
        • 使用新的$replaceOne 运算符计算新值。请注意Image 是如何根据其自身的值($Image)直接修改的。

      【讨论】:

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