Mongo将字符串数组更新为嵌入对象数组

时间:2018-02-19 16:01:26

标签: mongodb

我的MongoDB中存储了一些数据。 “tags”字段实际上是Strings的数组,但我们必须更新模型以使用这些标记存储更多数据

当前模型文件

{
    "id" : "59e4aefd74f12800019ba565",
    "title" : "This is a title",
    "tags" : [ 
        "59b02e6f6b28ce0001f8c0a8", 
        "59b031886b28ce0001f8c0af", 
        "59ba8c1a5047570001a3c078"
    ]
}

更新后的所需模型

{
    "id" : "59e4aefd74f12800019ba565",
    "title" : "This is a title",
    "tags" : [ 
        {
            "id" : "5a82ff1d889a15000103b115",
            "internalName" : "Día Mundial de la Television"
        }, 
        {
            "id" : "59ba8c1a5047570001a3c078",
            "internalName" : "menu"
        }, 
        {
            "id" : "5a26ac73d0fc2e00017f286e",
            "internalName" : "oid_asdf_asd"
        }
    ],


}

现在标签是嵌入式对象(忘记internalName字段)。如何在不丢失这些数据的情况下更新标记字段?我尝试使用$ rename,但它对数组

效果不佳
db.test.update({}, {$rename: {'tags': 'tags2.id'}})

1 个答案:

答案 0 :(得分:1)

使用此very good answer中的概念,您可以通过使用 $map 运算符转换标记数组的聚合操作创建游标,迭代游标并更新您的收藏集使用 bulkWrite 。 汇总操作如下:

var cursor = db.test.aggregate([
    {
        "$project": {
            "tags": {
                "$map": {
                    "input": "$tags",
                    "as": "el",
                    "in": { 
                        "id": "$$el",
                        "internalName": { "$literal": "temp string" }
                    }
                }
            }
        }
    }
]);

运行批量更新:

var bulkUpdateOps = [];

cursor.forEach(doc => {
    const { _id, tags } = doc;
    bulkUpdateOps.push({
        "updateOne": {
           "filter": { _id },
           "update": { "$set": { tags } },
           "upsert": true
        }
    });

    if (bulkUpdateOps.length === 1000) {
        db.test.bulkWrite(bulkUpdateOps);  
        bulkUpdateOps = [];                 
    }
}); 

if (bulkUpdateOps.length > 0) {
    db.test.bulkWrite(bulkUpdateOps);
}