Mongoose findOneAndUpdate投影无法省略_id字段问题咨询
Mongoose findOneAndUpdate投影无法移除_id字段的解决方案
问题本质
你遇到的问题源于Mongoose的Document实例特性:当显式指定**包含部分字段(值为1)**并搭配_id:0时,返回的Document对象会基于Schema默认保留_id属性,忽略投影中的_id:0设置。只有当仅使用排除规则(如单独_id:0),或者返回普通JS对象时,投影规则才会完全生效。
可行解决方案
1. 启用lean()选项(推荐)
添加lean()后,Mongoose会跳过创建Document实例,直接返回原始MongoDB文档对象,此时投影规则严格生效:
const userReturnFormat = { email: 1, name: 1, surname: 1, _id: 0 } const updatedUser = await UserModel.findOneAndUpdate( { registerId: params.user.registerId }, { $set: data }, { new: true, projection: userReturnFormat, lean: true } ) as User;
返回结果将严格匹配投影:只包含email、name、surname,无_id字段。
2. 用select()链式定义投影
也可以通过select()方法替代projection参数,配合lean()确保效果:
const updatedUser = await UserModel.findOneAndUpdate( { registerId: params.user.registerId }, { $set: data }, { new: true, lean: true } ).select(userReturnFormat) as User;
3. 全局禁用模型_id(谨慎使用)
如果业务中完全不需要该模型的_id字段,可以在Schema定义时关闭自动生成:
const UserSchema = new mongoose.Schema({ email: String, name: String, surname: String, registerId: String }, { _id: false }); const UserModel = mongoose.model('User', UserSchema);
此方法会影响该模型所有查询,需确认无业务依赖_id后使用。
验证结果
使用上述推荐方法后,返回结果与你期望一致:
{ email: 'j_doe@example.com', name: 'JOHN', surname: 'DOE' }
内容的提问来源于stack exchange,提问作者MKD
相关产品推荐
相关产品推荐

