更新MongoDB集合文档中的嵌套键值

更新MongoDB集合文档中的嵌套键值,mongodb,mongoose,mongodb-query,Mongodb,Mongoose,Mongodb Query,我的MongoDB(Atlas)数据库中有这个集合,代表用户的练习日志: [ { _id: ObjectId("...") <--- Exercise ID exerciseName: "Bench Press", sets: [ { _id: ObjectId("...") <--- Set ID weight: 100 reps: 1

我的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
  }
]
获取正确的练习日志。从那以后,我想我可以使用.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更改为新的。我认为通过使用spread操作符,对象的值会被保留,除了跟随操作符的值?如何实现在更新数据库中的权重、重复次数和注释值的同时保留旧id和createdAt的解决方案?

您可以在单个查询中同时执行
查找
更新
试试这个:

db.Workout.updateOne(
{
“集合id”:对象id(“6039709fe0c7d52970d3fa2f”)
},
{
$set:{
“套.$重量”:101,
“套.$.reps”:11,
“集.$.notes”:“已更新”
}
}
);
猫鼬:

Exercise.updateOne(
{
“集合id”:对象id(“6039709fe0c7d52970d3fa2f”)
},
{
“套.$重量”:101,
“套.$.reps”:11,
“集.$.notes”:“已更新”
}
).exec();

谢谢,这很有效。是否有一种方法可以检查查询是否已执行,例如如果未执行则返回错误?这与您处理的其他查询相同。使用
等待
然后().catch()
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();
}