我在表单的集合中有很多mongodb文档:
{
....
"URL":"www.abc.com/helloWorldt/..."
.....
}
我想,以取代helloWorldt
与helloWorld
来获得:
{
....
"URL":"www.abc.com/helloWorld/..."
.....
}
如何为我的收藏集中的所有文档实现这一目标?
Answers:
db.media.find({mediaContainer:"ContainerS3"}).forEach(function(e,i) {
e.url=e.url.replace("//a.n.com","//b.n.com");
db.media.save(e);
});
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)); })
如今,
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/..." }
{ URL: { $regex: /helloWorldt/ } }
)是match查询,用于过滤要更新的文档(包含的文档"helloWorldt"
),并且该文档可以使查询更快。$set: { URL: {...
)是更新聚合管道(请注意方括号表示使用聚合管道):
$set
是一个新的聚合运算符(Mongo 4.2
),在这种情况下将替换字段的值。$replaceOne
运算符计算的。请注意如何URL
根据其自身的值($URL
)直接进行修改。前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 ] }
]
}}
}]
)
find
吗?
$regex
运算符后面的正斜杠(即$regex: "/helloWorldt/"
)是必需的正则表达式分隔符。在示例中的其他任何地方,正斜杠都是URL路径定界符,可能没有必要。仅当OP具有要保留的包含/ helloWorldthirsty /的URL时,才需要使用它们。
当前,您不能使用字段的值来更新它。因此,您必须遍历文档并使用函数更新每个文档。这里有一个示例说明您如何执行此操作:MongoDB:使用同一文档中的数据更新文档
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});
});
});
我对所选答案(@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));
})
有时,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.用sed(对于Linux终端)或任何其他工具替换.json文件中的字符串。
sed -i 's/oldstring/newstring/g' products.json
4.使用带有--drop标签的mongoimport导入.json集合,在导入之前它将删除该集合
mongoimport --db=<db_name> --drop --collection products <products.json
或者,您可以使用--uri在mongoimport和mongodump中进行连接
例
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/
现在您可以做到!
我们可以使用Mongo脚本即时处理数据。这个对我有用!
我使用此脚本来更正我的地址数据。
当前地址示例:“第五大街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);
}
}
希望这可以帮助!
这可以通过Regex
在方法的第一部分中使用来完成replace
,它将g
用第二个字符串替换该字符串的[如果在regex模式中所有]出现,则这与Javascript中的regex相同,例如:
const string = "www.abc.com/helloWorldt/...";
console.log(string);
var pattern = new RegExp(/helloWorldt/)
replacedString = string.replace(pattern, "helloWorld");
console.log(replacedString);
由于regex替换了字符串,现在我们可以通过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/" }
>
以防万一,如果您使用的是此处回答的示例,并且在运行替换脚本时获得“更新的0条现有记录”,请检查您的客户端是否已连接到允许您存储/写入更改的主MongoDB节点。
如果您要搜索子字符串,然后将其替换为另一个字符串,则可以尝试以下操作,
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);
}
})