mongodb 如何替换mongodb文档中的子字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12589792/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to replace substring in mongodb document
提问by user1071979
I have a lot of mongodb documents in a collection of the form:
我在以下形式的集合中有很多 mongodb 文档:
{
....
"URL":"www.abc.com/helloWorldt/..."
.....
}
I want to replace helloWorldt
with helloWorld
to get:
我想,以取代helloWorldt
与helloWorld
来获得:
{
....
"URL":"www.abc.com/helloWorld/..."
.....
}
How can I achieve this for all documents in my collection?
如何为我的收藏中的所有文档实现这一点?
回答by Naveed
db.media.find({mediaContainer:"ContainerS3"}).forEach(function(e,i) {
e.url=e.url.replace("//a.n.com","//b.n.com");
db.media.save(e);
});
回答by Xavier Guihot
Nowadays,
如今,
- starting
Mongo 4.2
,db.collection.updateMany
(alias ofdb.collection.update
) can accept an aggregation pipeline, finally allowing the update of a field based on its own value. - starting
Mongo 4.4
, the new aggregation operator$replaceOne
makes it very easy to replace part of a string.
- 开始
Mongo 4.2
,db.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/..." }
- The first part (
{ URL: { $regex: /helloWorldt/ } }
) is the match query, filtering which documents to update (the ones containing"helloWorldt"
) and is just there to make the query faster. - The second part (
$set: { URL: {...
) is the update aggregation pipeline (note the squared brackets signifying the use of an aggregation pipeline):$set
is a new aggregation operator (Mongo 4.2
) which in this case replaces the value of a field.- The new value is computed with the new
$replaceOne
operator. Note howURL
is modified directly based on the its own value ($URL
).
- 第一部分 (
{ URL: { $regex: /helloWorldt/ } }
) 是匹配查询,过滤要更新的文档(包含 的文档"helloWorldt"
),只是为了加快查询速度。 - 第二部分 (
$set: { URL: {...
) 是更新聚合管道(注意方括号表示使用聚合管道):$set
是一个新的聚合运算符 (Mongo 4.2
),在这种情况下它替换字段的值。- 使用 new
$replaceOne
运算符计算新值。请注意如何URL
直接根据其自身的值 ($URL
) 进行修改。
Before Mongo 4.4
and starting Mongo 4.2
, due to the lack of a proper string $replace
operator, we have to use a bancal mix of $concat
and $split
:
前Mongo 4.4
和开始Mongo 4.2
,由于缺乏适当的字符串的$replace
操作,我们必须使用的bancal混合$concat
和$split
:
db.collection.updateMany(
{ URL: { $regex: "/helloWorldt/" } },
[{
$set: { URL: {
$concat: [
{ $arrayElemAt: [ { $split: [ "$URL", "/helloWorldt/" ] }, 0?] },
"/helloWorld/",
{ $arrayElemAt: [ { $split: [ "$URL", "/helloWorldt/" ] }, 1?] }
]
}}
}]
)
回答by Louisa
Currently, you can't use the value of a field to update it. So you'll have to iterate through the documents and update each document using a function. There's an example of how you might do that here: MongoDB: Updating documents using data from the same document
目前,您不能使用字段的值来更新它。因此,您必须遍历文档并使用函数更新每个文档。这里有一个示例,说明如何执行此操作:MongoDB:使用同一文档中的数据更新文档
回答by Lukas Liesis
nodejs. Using mongodb package from npm
节点。使用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});
});
});
回答by Michael Michelis
To replace ALLoccurrences of the substring in your document use:
要替换文档中所有出现的子字符串,请使用:
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);
});
回答by Himel Nag Rana
The formatting of my comment to the selected answer (@Naveed's answer) has got scrambled - so adding this as an answer. All credit goes to Naveed.
我对所选答案(@Naveed 的答案)的评论的格式已被打乱 - 因此将其添加为答案。所有功劳都归功于 Naveed。
----------------------------------------------------------------------
-------------------------------------------------- --------------------
Just awesome. My case was - I have a field which is an array - so I had to add an extra loop.
太棒了。我的情况是 - 我有一个数组字段 - 所以我不得不添加一个额外的循环。
My query is:
我的查询是:
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));
})
回答by Ry Van
Using mongodump,bsondump and mongoimport.
使用 mongodump、bsondump 和 mongoimport。
Sometimes the mongodb collections can get little complex with nested arrays/objects etc where it would be relatively difficult to build loops around them. My work around is kinda raw but works in most scenarios regardless of complexity of the collection.
有时 mongodb 集合在嵌套数组/对象等方面可能会变得有点复杂,在这些情况下,围绕它们构建循环相对困难。我的工作有点原始,但无论集合的复杂性如何,都可以在大多数情况下使用。
1. Export The collection using mongodump into .bson
1. 使用 mongodump 将集合导出为 .bson
mongodump --db=<db_name> --collection=<products> --out=data/
2. Convert .bson into .json format using bsondump
2. 使用 bsondump 将 .bson 转换为 .json 格式
bsondump --outFile products.json data/<db_name>/products.bson
3. Replace the strings in the .json file with sed(for linux terminal) or with any other tools
3. 将 .json 文件中的字符串替换为 sed(对于 linux 终端)或任何其他工具
sed -i 's/oldstring/newstring/g' products.json
4. Import back the .json collection with mongoimport with --drop tag where it would remove the collection before importing
4. 使用带有 --drop 标签的 mongoimport 导入 .json 集合,它会在导入之前删除集合
mongoimport --db=<db_name> --drop --collection products <products.json
Alternatively you can use --uri for connections in both mongoimport and mongodump
或者,您可以在 mongoimport 和 mongodump 中使用 --uri 进行连接
example
例子
mongodump --uri "mongodb://mongoadmin:[email protected]:27017,10.148.0.8:27017,10.148.0.9:27017/my-dbs?replicaSet=rs0&authSource=admin" --collection=products --out=data/
回答by Dac Nguyen
Now you can do it!
现在你可以做到了!
We can use Mongo script to manipulate data on the fly. It works for me!
我们可以使用 Mongo 脚本来动态操作数据。这个对我有用!
I use this script to correct my address data.
我使用这个脚本来更正我的地址数据。
Example of current address: "No.12, FIFTH AVENUE,".
当前地址示例:“第五大道 12 号”。
I want to remove the last redundant comma, the expected new address ""No.12, FIFTH AVENUE".
我想去掉最后一个多余的逗号,预期的新地址“第五大道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);
}
}
Hope this helps!
希望这可以帮助!
回答by krishna Prasad
This can be done by using the Regex
in the first part of the method replace
and it will replace the [all if g
in regex pattern] occurrence(s) of that string with the second string, this is the same regex as in Javascript e.g:
这可以通过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);
Since the regex is replacing the string, now we can do this is MongoDB shell easily by finding and iterating with each element by the method forEach
and saving one by one inside the forEach
loop as below:
由于正则表达式正在替换字符串,现在我们可以通过 MongoDB shell 通过方法查找和迭代每个元素forEach
并在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/" }
>
回答by Sergey Shcherbakov
Just in case if you are using examples from the answers here and get "Updated 0 existing records" when running your replace script, check whether your client is connected to the primary MongoDB node that allows you to store/write changes.
以防万一,如果您使用此处的答案中的示例并在运行替换脚本时获得“更新的 0 个现有记录”,请检查您的客户端是否连接到允许您存储/写入更改的主 MongoDB 节点。