通过subStaffModel查询的数组对象无法新增自定义属性如何解决?
问题原因
- Mongoose的
find方法默认返回的是Mongoose Document实例,不是普通JavaScript对象,实例默认开启了strict模式,只能操作Schema中预先定义的字段,你新增的myName没有在subStaffModel对应的Schema中声明,直接赋值不会被写入实例。 - 额外小问题:你使用
map遍历但没有接收返回的新数组,如果只是遍历修改原数组元素,用forEach更符合语义,不过这不是属性不生效的核心原因。
解决方法
下面三种方案按需选择:
方案1:查询时添加lean()(最常用,性能最好)
lean()会让查询直接返回普通JS对象,支持任意新增自定义属性,修改代码如下:
// 只需要在find后加.lean() const data = await subStaffModel.find({ subStaffType: 3 }).lean(); // 后面的赋值操作直接生效 data.forEach((entry) => { entry.myName = "rabbani"; }); console.log(data);
这个方案的优势是查询性能更高,适合不需要用到Mongoose Document自带方法(比如save、validate等)的场景。
方案2:使用set方法新增属性(需要保留Document实例的场景)
如果你需要保留Document的内置方法,不想转成普通对象,可以用Mongoose Document自带的set方法,关闭strict校验写入自定义字段:
const data = await subStaffModel.find({ subStaffType: 3 }); data.forEach((entry) => { // 第三个参数关闭strict模式,允许写入未定义的字段 entry.set('myName', 'rabbani', { strict: false }); }); console.log(data);
方案3:手动转换为普通对象
你也可以在遍历的时候,主动调用toObject()方法把Document转成普通JS对象再修改,这种情况需要接收map返回的新数组使用:
const data = await subStaffModel.find({ subStaffType: 3 }); const newData = data.map((entry) => { const plainEntry = entry.toObject(); plainEntry.myName = "rabbani"; return plainEntry; }); console.log(newData);
内容的提问来源于stack exchange,提问作者rabbani sarkar
相关产品推荐
相关产品推荐

