高效的MongoDB查询将字段拆分为数组

时间:2018-02-21 19:10:08

标签: mongodb

此代码将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" }
    ]
)

这似乎是一项简单的数据库任务。必须有更好的方法......对吧?

1 个答案:

答案 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);
}