93

我在表单集合中有很多 mongodb 文档:

{
....
"URL":"www.abc.com/helloWorldt/..."
.....
}

我想替换helloWorldthelloWorld

{
....
"URL":"www.abc.com/helloWorld/..."
.....
}

如何为我的收藏中的所有文档实现这一点?

4

10 回答 10

147
db.media.find({mediaContainer:"ContainerS3"}).forEach(function(e,i) {
    e.url=e.url.replace("//a.n.com","//b.n.com");
    db.media.save(e);
});
于 2015-07-07T07:50:17.680 回答
62

如今,

  • 开始Mongo 4.2db.collection.updateMany(的别名db.collection.update)可以接受一个聚合管道,最后允许根据自己的值更新一个字段。
  • 开始Mongo 4.4,新的聚合运算符$replaceOne使得替换字符串的一部分变得非常容易。
// { URL: "www.abc.com/helloWorldt/..." }
// { URL: "www.abc.com/HelloWo/..." }
db.collection.updateMany(
  { URL: { $regex: /helloWorldt/ } },
  [{
    $set: { URL: {
      $replaceOne: { input: "$URL", find: "helloWorldt", replacement: "helloWorld" }
    }}
  }]
)
// { URL: "www.abc.com/helloWorld/..." }
// { URL: "www.abc.com/HelloWo/..." }
  • 第一部分 ( { URL: { $regex: /helloWorldt/ } }) 是匹配查询,过滤要更新的文档(包含 的文档"helloWorldt")并且只是为了使查询更快。
  • 第二部分 ( $set: { URL: {...) 是更新聚合管道(注意方括号表示使用聚合管道):
    • $set是一个新的聚合运算符 ( Mongo 4.2),在这种情况下它替换了字段的值。
    • 使用 new 运算符计算新值$replaceOne。请注意如何URL直接根据其自身的值 ( $URL) 进行修改。

Mongo 4.4开始之前Mongo 4.2,由于缺少适当的字符串运算符,我们必须使用和$replace的混合:$concat$split

db.collection.updateMany(
  { URL: { $regex: "/helloWorldt/" } },
  [{
    $set: { URL: {
      $concat: [
        { $arrayElemAt: [ { $split: [ "$URL", "/helloWorldt/" ] }, 0 ] },
        "/helloWorld/",
        { $arrayElemAt: [ { $split: [ "$URL", "/helloWorldt/" ] }, 1 ] }
      ]
    }}
  }]
)
于 2019-06-12T06:57:20.363 回答
8

目前,您不能使用字段的值来更新它。因此,您必须遍历文档并使用函数更新每个文档。这里有一个示例说明您可以如何执行此操作:MongoDB:使用同一文档中的数据更新文档

于 2012-09-25T20:37:40.060 回答
6

使用 mongodump、bsondump 和 mongoimport。

有时 mongodb 集合对于嵌套数组/对象等可能会变得不太复杂,在这些集合中围绕它们构建循环相对困难。我的工作有点原始,但在大多数情况下都适用,无论集合的复杂性如何。

1. 使用 mongodump 将集合导出到 .bson

mongodump --db=<db_name> --collection=<products> --out=data/

2.使用bsondump将.bson转换成.json格式

bsondump --outFile products.json data/<db_name>/products.bson

3. 将 .json 文件中的字符串替换为 sed(用于 linux 终端)或任何其他工具

sed -i 's/oldstring/newstring/g' products.json

4.使用带有--drop标签的mongoimport导入.json集合,它将在导入之前删除集合

mongoimport --db=<db_name>  --drop --collection products <products.json

或者,您可以在 mongoimport 和 mongodump 中使用 --uri 进行连接

例子

mongodump --uri "mongodb://mongoadmin:mystrongpassword@10.148.0.7:27017,10.148.0.8:27017,10.148.0.9:27017/my-dbs?replicaSet=rs0&authSource=admin" --collection=products --out=data/
于 2019-04-02T04:30:22.153 回答
6

要替换文档中出现的所有子字符串,请使用:

db.media.find({mediaContainer:"ContainerS3"}).forEach(function(e,i) {
var find = "//a.n.com";
var re = new RegExp(find, 'g');
e.url=e.url.replace(re,"//b.n.com");
db.media.save(e);
});
于 2018-08-14T17:31:41.793 回答
5

节点。使用来自 npm 的 mongodb 包

db.collection('ABC').find({url: /helloWorldt/}).toArray((err, docs) => {
  docs.forEach(doc => {
    let URL = doc.URL.replace('helloWorldt', 'helloWorld');
    db.collection('ABC').updateOne({_id: doc._id}, {URL});
  });
});
于 2016-07-25T18:42:08.120 回答
4

我对所选答案(@Naveed 的答案)的评论的格式已被打乱 - 因此将其添加为答案。所有功劳归于 Naveed。

-------------------------------------------------- --------------------

太棒了。我的情况是——我有一个数组字段——所以我不得不添加一个额外的循环。

我的查询是:

db.getCollection("profile").find({"photos": {$ne: "" }}).forEach(function(e,i) {
    e.photos.forEach(function(url, j) {
        url = url.replace("http://a.com", "https://dev.a.com");
        e.photos[j] = url;
    });
    db.getCollection("profile").save(e);
    eval(printjson(e));
})
于 2017-10-11T06:20:42.150 回答
1

这可以通过Regex在方法的第一部分中使用来完成replace,它将g用第二个字符串替换该字符串的 [all if in regex pattern] 出现,这与 Javascript 中的正则表达式相同,例如:

const string = "www.abc.com/helloWorldt/...";
console.log(string);
var pattern = new RegExp(/helloWorldt/)
replacedString = string.replace(pattern, "helloWorld");
console.log(replacedString);

由于正则表达式正在替换字符串,现在我们可以通过该方法查找和迭代每个元素forEach并在循环中一个一个地保存,从而轻松地做到这一点是 MongoDB shell forEach,如下所示:

> db.media.find()
{ "_id" : ObjectId("5e016628a16075c5bd26fbe3"), "URL" : "www.abc.com/helloWorld/" }
{ "_id" : ObjectId("5e016701a16075c5bd26fbe4"), "URL" : "www.abc.com/helloWorldt/" }
> 
> db.media.find().forEach(function(o) {o.URL = o.URL.replace(/helloWorldt/, "helloWorld"); printjson(o);db.media.save(o)})
{
    "_id" : ObjectId("5e016628a16075c5bd26fbe3"),
    "URL" : "www.abc.com/helloWorld/"
}
{
    "_id" : ObjectId("5e016701a16075c5bd26fbe4"),
    "URL" : "www.abc.com/helloWorld/"
}
> db.media.find()
{ "_id" : ObjectId("5e016628a16075c5bd26fbe3"), "URL" : "www.abc.com/helloWorld/" }
{ "_id" : ObjectId("5e016701a16075c5bd26fbe4"), "URL" : "www.abc.com/helloWorld/" }
>
于 2019-12-24T01:37:59.290 回答
1

现在你可以做到了!

我们可以使用 Mongo 脚本来动态操作数据。这个对我有用!

我使用这个脚本来更正我的地址数据。

当前地址示例:“第五大道 12 号”。

我想删除最后一个多余的逗号,即预期的新地址“第五大道 12 号”。

var cursor = db.myCollection.find().limit(100);

while (cursor.hasNext()) {
  var currentDocument = cursor.next();

  var address = currentDocument['address'];
  var lastPosition = address.length - 1;

  var lastChar = address.charAt(lastPosition);

  if (lastChar == ",") {

    var newAddress = address.slice(0, lastPosition);


    currentDocument['address'] = newAddress;

    db.localbizs.update({_id: currentDocument._id}, currentDocument);

  }
}

希望这可以帮助!

于 2015-11-03T12:58:39.400 回答
1

如果你想搜索一个子字符串,并用另一个替换它,你可以尝试如下,

    db.collection.find({ "fieldName": /.*stringToBeReplaced.*/ }).forEach(function(e, i){
        if (e.fieldName.indexOf('stringToBeReplaced') > -1) {
          e.content = e.content.replace('stringToBeReplaced', 'newString');
          db.collection.update({ "_id": e._id }, { '$set': { 'fieldName': e.fieldName} }, false, true);
        }
    }) 
于 2020-07-09T08:31:16.147 回答