此代码将nicknames
集合中的cities
字段拆分为数组,但速度有所缓慢:
db.cities
.find()
.snapshot()
.forEach(function(el) {
el.nicknames = el.nicknames.split('->')
db.cities.save(el)
})
此代码还将nicknames
集合中的cities
字段拆分为一个数组,速度要快得多,但它会暂时导致数据库大小翻倍,从而导致数据库崩溃。
db.cities.aggregate(
[
{ "$addFields": {
"nicknames": { "$split": [ "$nicknames", "->" ] }
}},
{ "$out": "cities" }
]
)
这似乎是一项简单的数据库任务。必须有更好的方法......对吧?
答案 0 :(得分:1)
是的,利用 bulkWrite
方法进行有效的批量更新。您可以将更新操作拆分为大型集合的批处理。
使用聚合操作中的光标(减去最后一个 $out
管道),您可以将批量更新操作组合为:
let bulkUpdateOps = [];
const cursor = db.cities.aggregate([
{ "$project": { "nicknames": { "$split": [ "$nicknames", "->" ] } } }
]);
cursor.forEach(doc => {
const { _id, nicknames } = doc;
bulkUpdateOps.push({
"updateOne": {
"filter": { _id },
"update": { "$set": { nicknames } },
"upsert": true
}
});
if (bulkUpdateOps.length === 1000) {
db.cities.bulkWrite(bulkUpdateOps);
bulkUpdateOps = [];
}
});
if (bulkUpdateOps.length > 0) {
db.cities.bulkWrite(bulkUpdateOps);
}