重命名 MongoDB 数组中的字段

Mui*_*rik 1 mongodb

我需要更新集合中的字段名称。问题在于相关字段位于数组内。所以我试图确定正确的方法。我尝试这样做来完成重命名“plans”数组中存在的字段::

db.customers.updateMany( {}, { $rename: { "plans" : { "subscriptionType": "membershipType" } } } );
Run Code Online (Sandbox Code Playgroud)

但这是行不通的。处理数组中字段的这种转换的正确方法是什么?

数据如下:

{
  _id: 123,
  prop1: value,
  prop2: value,
  prop3: value,
  plans: [
    subscriptionType: value,
    otherProp: value,
    otherProp: value
  ]
}
Run Code Online (Sandbox Code Playgroud)

mic*_*ckl 5

您可以使用聚合框架的$addFields覆盖plans字段和$map运算符来重命名数组内的字段。然后你可以使用$out覆盖现有集合:

db.customers.aggregate([
    {
        $addFields: {
            plans: {
                $map:{
                    input: "$plans",
                    as: "plan",
                    in: {
                        membershipType: "$$plan.subscriptionType",
                        otherField: "$$plan.otherField",
                        otherField2: "$$plan.otherField2"
                    }
                }
            }
        }
    },
    {
        $out: "customers"
    }
])
Run Code Online (Sandbox Code Playgroud)

或者,您可以动态地执行此操作。在此解决方案中,您不必显式指定其他字段名称:

db.customers.aggregate([
    {
        $addFields: {
            plans: {
                $map:{
                    input: "$plans",
                    as: "plan",
                    in: {
                        $mergeObjects: [
                            { membershipType: "$$plan.subscriptionType" },
                            { 
                                $arrayToObject: {
                                    $filter: {
                                        input: { $objectToArray: "$$plan" },
                                        as: "plan",
                                        cond: { $ne: [ "$$plan.k", "subscriptionType" ] }
                                    }
                                } 
                            }
                        ]
                    }
                }
            }
        }
    },
    {
        $out: "customers"
    }
])
Run Code Online (Sandbox Code Playgroud)

使用$objectToArray$filter掉旧的键值对,并使用$mergeObjects将过滤后的对象与新的重命名字段组合起来。

  • 无论如何,我添加了“动态”方法 (2认同)
  • @mickl 效果惊人!你节省了我潜在的工作时间:D谢谢! (2认同)