在正确的字段中替换多值mongo

时间:2015-07-10 04:06:47

标签: regex mongodb mongodb-query

我有一个像这样的示例mongodb:

{
        "_id" : ObjectId("559e448dfb9fc95e5d00008c"),
        "title" : "Maps ",
        "link" : "https://www.youtube.com/embed/NmugSMBh_iI",
        "img" : "https://i.ytimg.com/vi/NmugSMBh_iI/default.jpg",
        "time" : "3:28",
        "des" : "Maroon 5 - Maps (Explicit)\r\n",
        "cat" : [
                "maroon5"
        ],
        "id" : 179,
        "date" : "2015-07-08T16:49:11+07:00"
}
{
        "_id" : ObjectId("559e451afb9fc95e5d00008d"),
        "title" : "Animals",
        "link" : "https://www.youtube.com/embed/qpgTC9MDx1o",
        "img" : "https://i.ytimg.com/vi/qpgTC9MDx1o/default.jpg",
        "time" : "4:40",
        "des" : "Maroon 5 - Animals\r\n",
        "cat" : [
                "maroon5"
        ],
        "id" : 180,
        "date" : "2015-07-08T16:49:11+07:00"
}

现在我想在每个“链接”字段中将此字符串“embed /”替换为“watch?v =”,如下所示:

"link" : "https://www.youtube.com/watch?v=/NmugSMBh_iI"

我该怎么做?

2 个答案:

答案 0 :(得分:2)

您将不得不循环浏览并逐个更改它们。 您可以使用以下代码在数据库中进行更改,但是,您可以将MongoDB的支持库用于您希望获得相同结果的任何语言。

var cursor = db.videos.find();
while ( cursor.hasNext() ) {
   var current = cursor.next();
   db.videos.update({_id: current._id}, {$set: {link: current.link.replace('embed/','watch?v=')}})
}

答案 1 :(得分:1)

如上所述,您需要循环收集结果,以便能够读取您要修改的值。 MongoDB更新运算符不支持“就地”执行此操作,并且目前不支持“regexReplce”运算符。虽然它会很好。

最有效的方法是使用"Bulk"操作API,并通过$regex进行一点查询过滤,以确保只更新那些需要更新的项目:

var bulk = db.tube.initializeUnorderedBulkOp(),
    count = 0;

db.tube.find({ 
   "link": /(youtube\.com)(\/embed)/ 
}).forEach(function(doc) {
    doc.link = doc.link.replace( 
        new RegExp("(youtube\.com)(\/embed\/)"), 
        new RegExp("$1/watch\?v=") );

    bulk.find({ "_id": doc._id }).updateOne({ "$set": { "link": doc.link } });
    count++;

    // Only send operations to server once in 1000 ops. And re-init.
    if ( count % 1000 == 0 ) {
        bulk.execute();
        bulk = db.tube.initializeUnorderedBulkOp();
    }
});

// Drain any queued operations
if ( count % 1000 != 0 )
    bulk.execute();

这是您最快的更新方式,因为请求是以“批次”处理的,这意味着来往服务器的流量更少。因此,速度更快。