如何替换mongodb文件中的子字符串

use*_*979 59 mongodb mongo-shell mongodb-.net-driver

我在形式的集合ABC中有很多mongodb文档:

{
....
"URL":"www.abc.com/helloWorldt/..."
.....
}
Run Code Online (Sandbox Code Playgroud)

我想用helloWorld最终输出替换helloWorldt:

{
....
"URL":"www.abc.com/helloWorld/..."
.....
}
Run Code Online (Sandbox Code Playgroud)

我如何为集合ABC中的所有文档实现此目的

小智 106

db.media.find({mediaContainer:"ContainerS3"}).forEach(function(e,i) {
    e.url=e.url.replace("//a.n.com","//b.n.com");
    db.media.save(e);
});
Run Code Online (Sandbox Code Playgroud)

  • 真棒.我的情况是 - 我有一个数组的字段 - 所以我不得不添加一个额外的循环.我的查询是:````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));})```` (3认同)
  • @doe“ e”表示找到的每个文档的副本。该副本具有其url值(区分大小写,请注意,这与问问者的“ url”不同)是根据其url的原始值更新的。“ e”将其所有原始字段保留为一个修改的字段。将e保存回集合中会覆盖原始的“ e”。这里不需要“ i”,可以将其从函数声明中删除。 (3认同)
  • 你能详细说明一下吗?它是如何工作的代码的含义是什么?对于其他用户? (2认同)

Xav*_*hot 10

开始Mongo 4.2db.collection.update()可以接受一个聚合管道,终于使基于另一个字段的字段的更新:

// { URL: "www.abc.com/helloWorldt/..." }
// { URL: "www.abc.com/HelloWo/..." }
db.collection.update(
  { URL: { $regex: "/helloWorldt/" } },
  [{
    $set: { URL: {
      $concat: [
        { $arrayElemAt: [ { $split: [ "$URL", "/helloWorldt/" ] }, 0 ] },
        "/helloWorld/",
        { $arrayElemAt: [ { $split: [ "$URL", "/helloWorldt/" ] }, 1 ] }
      ]
    }}
  }],
  { multi: true }
)
// { URL: "www.abc.com/helloWorld/..." }
// { URL: "www.abc.com/HelloWo/..." }
Run Code Online (Sandbox Code Playgroud)

这有点冗长,因为还没有合适的字符串$replace运算符。

  • 第一部分{ URL: { $regex: "/helloWorldt/" } }是匹配查询,用于过滤要更新的文档(带有“ hello world”拼写错误的文档)。

  • 第二部分[{ $set: { URL: ... } }]是更新聚合管道(请注意方括号表示使用聚合管道)。$set是一个新的聚合运算符,在这种情况下,它会创建/替换一个字段。新的值使用的混合古怪计算$concat$split缺乏适当的字符串的$replace操作。请注意如何URL根据其自身的值($URL)直接进行修改。

  • 不要忘记{ multi: true },否则只会更新第一个匹配的文档。


Lou*_*isa 8

目前,您无法使用字段的值来更新它.因此,您必须遍历文档并使用函数更新每个文档.这里有一个如何实现的示例:MongoDB:使用同一文档中的数据更新文档


小智 6

使用 mongodump、bsondump 和 mongoimport。

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

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

mongodump --db=<db_name> --collection=<products> --out=data/
Run Code Online (Sandbox Code Playgroud)

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

bsondump --outFile products.json data/<db_name>/products.bson
Run Code Online (Sandbox Code Playgroud)

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

sed -i 's/oldstring/newstring/g' products.json
Run Code Online (Sandbox Code Playgroud)

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

mongoimport --db=<db_name>  --drop --collection products <products.json
Run Code Online (Sandbox Code Playgroud)

或者,您可以在 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/
Run Code Online (Sandbox Code Playgroud)


Luk*_*kas 5

nodejs。从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});
  });
});
Run Code Online (Sandbox Code Playgroud)


小智 5

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

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);
});
Run Code Online (Sandbox Code Playgroud)

  • var不需要进入循环,因此请将它们放在前面。 (3认同)