为何MongoDB查询返回的Document用Object.keys()仅返回3个键?
Object.keys()无法获取MongoDB文档所有键的原因及解决办法
原因
Mongoose执行findById返回的不是普通JavaScript对象,而是Mongoose Document实例。这类实例的文档字段并非自身的可枚举属性,而是通过原型链的getter方法暴露出来的:
for...in循环会遍历对象自身及原型链上的所有可枚举属性,所以能输出文档的全部字段;Object.keys()仅返回对象自身的可枚举属性,因此只能拿到$__、$isNew、_doc这些Document实例自带的内部属性。
解决办法
有三种常用方式可以解决这个问题,按需选择:
- 将Document转为普通JS对象
使用Mongoose提供的toObject()或toJSON()方法,把实例转换为普通对象后再操作:
async update(id: string, updateGameDto: UpdateGameDto) { const game = await this.findOne(id); const gameObj = game.toObject(); // 转为普通对象 const keys = Object.keys(gameObj); // 现在能获取所有文档字段 const specificKeyByValue = Object.keys(gameObj).find(key => gameObj[key] === "SomeValue"); // ...后续逻辑 }
- 直接访问内部
_doc属性(不推荐)
Document实例的_doc属性存储了原始文档数据,可直接访问,但这是Mongoose内部属性,版本更新可能会变动:
const keys = Object.keys(game._doc);
- 查询时直接返回普通对象
在查询方法中添加.lean(),让Mongoose直接返回普通JS对象,省去后续转换步骤:
async findOne(id: string) { return await this.gameModel.findById(id).lean(); } async update(id: string, updateGameDto: UpdateGameDto) { const game = await this.findOne(id); const keys = Object.keys(game); // 直接获取所有字段 const specificKeyByValue = Object.keys(game).find(key => game[key] === "SomeValue"); // ...后续逻辑 }
内容的提问来源于stack exchange,提问作者Sylent
相关产品推荐
相关产品推荐

