我在Mongo中有一个形状如下的集合:
{
path: 'any string', // e.g., 'a,b,c,d,e'
}
我需要在此集合中的所有文档中找到'a'
并将其替换为另一个字符串,例如'1,2,3'
。我知道可以使用find()
,遍历结果并更新数据库中的结果来非常低效地完成此操作。是否有某种合计或批量操作可以使此操作更容易/更快(我正在使用Mongoose)?谢谢
答案 0 :(得分:2)
是否存在某种汇总或批量操作,可以使此操作更容易/更快
您可以运行MongoDB Aggregation Pipeline来处理查找和替换,然后遍历结果并发送unordered bulk update operations。
我将在mongo shell中编写以下示例以使其具有通用性,但对于等效的Mongoose,请参见-Model.aggregate()和Model.bulkWrite()以获取更多信息。
例如,如果您有以下三个文档:
a.target = '_blank'
要将{ "_id": 1, "path": "a,b,c,d" }
{ "_id": 2, "path": "b,a,c,d" }
{ "_id": 3, "path": "c,b,a" }
替换为a
的位置。使用聚合管道,创建一个名为1,2,3
的新字段来存储替换结果,如下所示:
newPath
这将输出如下内容:
db.collection.aggregate([
{"$addFields":{
"toBeRemoved": "a",
"replacement": "1,2,3",
}},
{"$addFields":{
"newPath": {
"$concat":[
{"$substrBytes":[
"$path",
0,
{ "$cond": {
"if": {
"$lt": [ {"$subtract": [{"$strLenBytes": "$path"}, {"$subtract": [ {"$strLenBytes": "$path"}, {"$indexOfBytes":["$path", "$toBeRemoved"]} ] } ]}, 0]
},
"then": 0,
"else": {"$subtract": [{"$strLenBytes": "$path"}, {"$subtract": [ {"$strLenBytes": "$path"}, {"$indexOfBytes":["$path", "$toBeRemoved"]} ] } ]}
}
}]},
"$replacement",
{"$substrBytes":[
"$path",
{"$add":[{
"$cond": {
"if": {
"$lt": [ {"$subtract": [{"$strLenBytes": "$path"}, {"$subtract": [ {"$strLenBytes": "$path"}, {"$indexOfBytes":["$path", "$toBeRemoved"]} ] } ]}, 0]
},
"then": 0,
"else": {"$subtract": [{"$strLenBytes": "$path"}, {"$subtract": [ {"$strLenBytes": "$path"}, {"$indexOfBytes":["$path", "$toBeRemoved"]} ] } ]}
}
}, {"$strLenBytes": "$toBeRemoved"}
]},
{"$subtract": [
{"$strLenBytes": "$path"},
{"$add": [
{"$indexOfBytes":["$path", "$toBeRemoved"]},
{"$strLenBytes": "$toBeRemoved"}
]}
]}
]}
]
},
}},
{"$project": {
"toBeRemoved":0,
"replacement":0,
}}
])
请注意,上面的汇总已经编写完毕,因此可以重新用于其他替换。也就是说,将{ "_id": 1, "path": "a,b,c,d", "newPath": "1,2,3,b,c,d" }
{ "_id": 2, "path": "b,a,c,d", "newPath": "b,1,2,3,c,d" }
{ "_id": 3, "path": "c,b,a", "newPath": "c,b,1,2,3" }
替换为toBeRemoved
,并将b
替换为replacement
,它的工作原理类似。
上面的聚合管道应适用于MongoDB v3.4 +。还值得一提的是,目前有一个开放票证SERVER-11947,可为聚合语言添加正则表达式支持。
然后您可以遍历结果,并发送无序的x,y
更新操作,如下例:
bulkWrite