原文:
_id: "54022f8b705ebb4010170f02",
exercises: [
{
name: "Bench"
},
date: "2014-08-30T20:31:22.982Z"
所需更新:
_id: "54022f8b705ebb4010170f02",
exercises: [
{
name: "Bench",
sets: [{weight: 275, reps: 5}]
},
date: "2014-08-30T20:31:22.982Z"
我已尝试过这方面的事情(没有工作),但我很难将一套装置放到正确的位置:
db.workouts.update(
{ _id: ObjectId('54022f8b705ebb4010170f02'), "exercises.name":'Bench'},
{
$push:
{
sets:
{
weight: 275,
reps: 5,
}
}
}
)
另外,如果有更好的方法来建模,请高兴地提出建议。
答案 0 :(得分:1)
此处的推送操作应该没问题,但您需要做的是确定要将对象推送到的数组位置。您通过在查询部分中查找“Bench”来完成一半更新。现在你需要与positional $
运算符进行识别,并且还要意识到“sets”是“exercise”下的一个元素,因此需要以这种方式标注:
db.workouts.update(
{
"_id": ObjectId("54022f8b705ebb4010170f02"),
"exercises.name":"Bench"
},
{
"$push": {
"exercises.$.sets": {
"weight": 275,
"reps": 5
}
}
}
)
所以说,使用$push
添加新的“集合”项目或其他“集合”项目不是问题,因此如果您的模型基本上是“仅附加”,那么这很好。唯一的问题是,如果您打算在某个未知的位置“更新”内部数组元素。例如,将元素“weight”275更改为6“reps”。
出现这个问题是因为positional $
运算符仅用于捕获数组的“第一个”匹配位置,并且它始终是“外部”数组或“练习”。所以你不能这样做:
db.workouts.update(
{
"_id": ObjectId("54022f8b705ebb4010170f02"),
"exercises.sets.weight": 275
},
{
"$set": {
"exercises.$.sets.$.weight": 285
}
}
)
但是对于一个已知职位,你可以:
db.workouts.update(
{
"_id": ObjectId("54022f8b705ebb4010170f02"),
"exercises.sets.weight": 275
},
{
"$set": {
"exercises.$.sets.0.weight": 285
}
}
)
但是“第一个”数组位置始终是返回的索引,而不是内部数组。
在考虑在建模中使用嵌套数组时,这是最重要的事情。