Mongoose更新嵌套数组异常:插入缺字段且更新覆盖旧值
问题分析与解决方案
嘿,我一眼就瞅出你这俩问题的根源了——全是更新操作的语法用错啦!
问题1:插入时grids字段为空,更新时旧数据被删除
你现在的代码用$set直接覆盖了defender.placements整个对象,这就导致每次更新时,之前存的cruisers(或其他船型)数据会被完全替换掉,根本不是追加新船只。另外,你把$addToSet嵌套在$set的字段值里,这是MongoDB绝对不允许的语法——更新操作符不能放在$set的对象内部,所以grids字段根本没被正确处理,自然是空的。
正确的更新代码
你需要针对特定的船型数组,用$addToSet(或$push)来添加完整的船只对象,而不是用$set替换整个placements。修改后的代码如下:
await GameState.update( { _id: testId }, { $addToSet: { // 动态指定船型数组,添加完整的Ship对象 [`defender.placements.${shipType}`]: { status: utils.shipStatus.float, direction: shipDirection, size: coordinates.length, grids: coordinates }, occupyGrids: coordinates, adjacentGrids: closeGrids } }, (err, gm) => { if (err) { return res.send(err); } } );
几个关键点说明
- 用
$addToSet而非$set:$addToSet会把新的船只对象追加到对应船型的数组里,不会覆盖原有数据;如果你的业务允许同一船型数组存在重复对象,就换成$push。 - 动态字段路径:用模板字符串
[defender.placements.${shipType}]可以根据shipType的值(比如cruisers)动态定位到目标数组,不用写死路径。 - 完整构造Ship对象:把
grids字段直接包含在要添加的对象里,这样MongoDB会正确把坐标数组存入grids字段。
这样修改后,你再执行插入操作时,grids字段就能正确保存坐标,后续更新也只会追加新的船只数据,不会删除旧的啦!
内容的提问来源于stack exchange,提问作者Aon
相关产品推荐
相关产品推荐

