首页 > 解决方案 > 更新 MongoDB 集合文档中的嵌套键值

问题描述

我的 MongoDB (Atlas) 数据库中有这个集合,它代表用户的锻炼日志:

[
  {
    _id: ObjectId("...") <--- Exercise ID
    exerciseName: "Bench Press",
    sets: [
      {
        _id: ObjectId("...") <--- Set ID
        weight: 100
        reps: 10
        createdAt: 1614461387587
        notes: ""
      },
      {
        // More set data objects
      }
    ]
  },
  {
    // More exercise data objects
  }
]

我正在我的应用程序中创建一个功能,允许用户编辑一组,以防他们输入不正确。目前,我通过获取该集合所属的用户练习来做到这一点:

const user = checkAuth(context);
let exerciseLog = await Exercise.findOne({
  _id: exerciseId,
  user: user.id,
  "sets._id": setId,
});

哪个得到正确的锻炼日志。从那里,我想我可以使用 .find() 函数来获取需要编辑的集合并将值替换为新值,如下所示:

const set = exerciseLog.sets.find((set) => set.id === setId);
if (set) {
  const newSet = { ...set, weight, reps, notes };
  const setIndex = exerciseLog.sets.findIndex(
    (set) => set.id === setId
  );
  exerciseLog.sets.splice(setIndex, 1, newSet);
  await exerciseLog.save();
}

然而,这种方法一旦执行,确实会替换重量、次数和音符的值,但会完全删除 createdAt 键并将 set id 更改为新的。我认为通过使用扩展运算符,对象的值将被保留,除了运算符后面的值?如何实现一个解决方案,在该解决方案中保留旧的 id 和 createdAt,同时更新数据库中的 weight、reps 和 notes 值?

标签: mongodbmongoosemongodb-query

解决方案


您可以在单个查询中find同时执行update此操作试试这个:

db.Workout.updateOne(
    {
        "sets._id": ObjectId("6039709fe0c7d52970d3fa2f")
    },
    {
        $set: {
            "sets.$.weight": 101,
            "sets.$.reps": 11,
            "sets.$.notes": "Updated"
        }
    }
);

猫鼬:

Exercise.updateOne(
    {
        "sets._id": ObjectId("6039709fe0c7d52970d3fa2f")
    },
    {
        "sets.$.weight": 101,
        "sets.$.reps": 11,
        "sets.$.notes": "Updated"
    }
).exec();

推荐阅读