通过 MongoDB 中的其他字段更新特定索引处的数组

Update array at specific index by other filed in MongoDB

我有一个 collection,由 namedata 组成。

data 是一个有 2 个元素的数组,每个元素是 object 和 codeqty.

{
    "_id" : ObjectId("605c666a15d2612ed0afedd2"),
    "name" : "Anna",
    "data" : [
        {
            "code" : "a",
            "qty" : 3
        },
        {
            "code" : "b",
            "qty" : 4
        }
    ]
},
{
    "_id" : ObjectId("605c666a15d2612ed0afedd3"),
    "name" : "James",
    "data" : [
        {
            "code" : "c",
            "qty" : 5
        },
        {
            "code" : "d",
            "qty" : 6
        }
    ]
}

我想将第一个元素的 code 更新为其文档的 name。我要的结果是

{
    "_id" : ObjectId("605c666a15d2612ed0afedd2"),
    "name" : "Anna",
    "data" : [
        {
            "code" : "Anna",
            "qty" : 3
        },
        {
            "code" : "b",
            "qty" : 4
        }
    ]
},
{
    "_id" : ObjectId("605c666a15d2612ed0afedd3"),
    "name" : "James",
    "data" : [
        {
            "code" : "James",
            "qty" : 5
        },
        {
            "code" : "d",
            "qty" : 6
        }
    ]
}

我只是 google 了解如何:

  1. 在特定索引处更新数组 ()
db.Collection.updateMany(
    { },
    {
        $set:{
            'data.0.code': '$name'
        }
    }
)

但是data数组中第一个元素的代码是一个字符串'$name',而不是一个值(Anna, James)

{
    "_id" : ObjectId("605c666a15d2612ed0afedd2"),
    "name" : "Anna",
    "data" : [
        {
            "code" : "$name",
            "qty" : 3
        },
        {
            "code" : "b",
            "qty" : 4
        }
    ]
},
{
    "_id" : ObjectId("605c666a15d2612ed0afedd3"),
    "name" : "James",
    "data" : [
        {
            "code" : "$name",
            "qty" : 5
        },
        {
            "code" : "d",
            "qty" : 6
        }
    ]
}
  1. 用另一个字段的值更新一个字段。我需要使用管道更新():updateMany 的第二个参数是数组(管道)
db.Collection.updateMany(
    { },
    [{
        $set:{
            'data.0.code': '$name'
        }
    }]
)

并且它将字段 0 添加到 data 数组

中的每个元素
{
    "_id" : ObjectId("605c666a15d2612ed0afedd2"),
    "name" : "Anna",
    "data" : [
        {
            "0" : {
                "code" : "Anna"
            },
            "code" : "a",
            "qty" : 3
        },
        {
            "0" : {
                "code" : "Anna"
            },
            "code" : "b",
            "qty" : 4
        }
    ]
},
{
    "_id" : ObjectId("605c666a15d2612ed0afedd3"),
    "name" : "James",
    "data" : [
        {
            "0" : {
                "code" : "James"
            },
            "code" : "c",
            "qty" : 5
        },
        {
            "0" : {
                "code" : "James"
            },
            "code" : "d",
            "qty" : 6
        }
    ]
}

我找不到这个案例的解决方案。谁能帮我?如何通过其他字段更新固定索引处的数组。感谢阅读!

1. update array at a specific index

您不能将内部字段用作另一个字段的值,它只有在您有外部值要更新时才有效,例如 { $set: { "data.0.code": "Anna" } }

2. update a field by the value of another field

使用聚合管道更新不允许访问 data.0.code 语法。


您可以尝试在聚合管道更新中使用$reduce

  • $reduce 迭代 data 数组的循环,在 reduce 的 initialValue 中设置空数组,检查条件如果 initialValue 数组大小为零然后用 name 替换 code并使用 $mergeObjects 与当前对象合并,否则 return 当前对象,
  • $concatArrays 将当前对象与 initialValue 数组连接起来
db.collection.update({},
  [{
    $set: {
      data: {
        $reduce: {
          input: "$data",
          initialValue: [],
          in: {
            $concatArrays: [
              "$$value",
              [
                {
                  $cond: [
                    { $eq: [{ $size: "$$value" }, 0] },
                    { $mergeObjects: ["$$this", { code: "$name" }] },
                    "$$this"
                  ]
                }
              ]
            ]
          }
        }
      }
    }
  }],
  { multi: true }
)

Playground

我认为另一种方法更容易。 只需保存之前的模型并在之后使用它进行更新

var annaModel = nameModel.findOne({_id: "605c666a15d2612ed0afedd2" })

nameModel.findOneAndUpdate({_id: "605c666a15d2612ed0afedd2"},{$set:{'data.0.code': annaModel.name}})