Mongoose查询返回文档出现与_id相同的额外id字段问题求助
问题原因与解决办法
嘿,这个问题我之前开发Mongoose项目时也碰到过,其实原因很清晰——你开启了Mongoose虚拟属性的序列化功能,而那个额外的id字段正是Mongoose默认给每个Schema自动添加的虚拟属性。
为什么会出现这个id字段?
Mongoose默认会为所有文档生成一个名为id的虚拟属性,它的值就是MongoDB原生的_id字段转换为字符串后的结果(毕竟_id是ObjectId类型,有时候我们需要字符串格式的ID来方便使用)。
而你在定义Crop Schema的时候,设置了如下选项:
{ toJSON: { virtuals: true }, toObject: { virtuals: true }, }
这就意味着当Mongoose把文档序列化成JSON(比如你用res.send(crops)返回给前端)或者普通JavaScript对象时,所有虚拟属性都会被包含进去,所以就出现了和_id值完全一致的id字段。
解决办法(三种可选方案)
根据你的需求,你可以选下面任意一种方式来移除这个额外的id字段:
方案1:完全关闭虚拟属性序列化
如果你不需要任何虚拟属性出现在返回结果里,直接把Schema选项中的virtuals设为false即可:
const cropSchema = new mongoose.Schema({ nameOfCrop:{ type:String, lowercase:true, required:'Please enter the name of the crop', trim:true }, imageOfCrop:String, soilType: String, waterNeeded:String, tagCrop:String,//forage, vegetable, oilseeds etc. pesticideForCrop:[{ type:mongoose.Schema.Types.ObjectId, ref:'Pesticide' } ] }, { toJSON: { virtuals: false }, toObject: { virtuals: false } });
方案2:保留其他虚拟属性,仅移除id
如果你自己定义了其他需要保留的虚拟属性,可以通过transform函数在序列化时删除id字段:
const cropSchema = new mongoose.Schema({ // 你的字段定义... }, { toJSON: { virtuals: true, transform: function(doc, ret) { delete ret.id; // 移除虚拟的id字段 return ret; } }, toObject: { virtuals: true, transform: function(doc, ret) { delete ret.id; return ret; } } });
方案3:直接关闭默认的id虚拟属性
你也可以在Schema选项里直接禁用Mongoose默认的id虚拟属性,这样不管是否开启虚拟属性序列化,这个字段都不会出现:
const cropSchema = new mongoose.Schema({ // 你的字段定义... }, { id: false, // 关闭默认的id虚拟属性 toJSON: { virtuals: true }, toObject: { virtuals: true } });
修改完成后重启你的服务,再用Postman查询,就能看到返回结果里只剩下原生的_id字段啦。
内容的提问来源于stack exchange,提问作者Parikshit Hooda
相关产品推荐
相关产品推荐

