Nest.js中使用Mongoose模型的.find方法始终返回空数组
在Nest.js项目中,数据库内存在对应ID的数据,但使用Mongoose模型的.find方法查询时始终返回空数组,以下是相关代码及日志信息:
database.service.ts
async updateReply(id: string, attributes: Partial<ReplyDto>) { console.log('Path request update reply with id: ' + id + ' and body:', attributes); const reply = await this.replyModel.find({ _id: id }); // 之前的查询更新方式: // // const reply = await this.replyModel.findOneAndUpdate( // { _id: new mongoose.Types.ObjectId(id) }, // { $set: attributes }, // { new: true } // ); console.log('Reply updated: ', reply); return reply; }
replies.service.ts
async updateReply(id: string, body: UpdateReplyDto) { console.log('Path request update reply with id: ' + id + ' and body:', body); return await this.databaseService.updateReply(id, body); }
replies.controller.ts
@Patch('/update/:id') updateReplyById(@Param('id') id: string, @Body() body: UpdateReplyDto) { console.log('Path request update reply with id: ' + id + ' and body:', body); return this.repliesService.updateReply(id, body); }
update-reply.dto.ts
import { IsArray, IsNumber, IsOptional, IsString } from "class-validator"; export class UpdateReplyDto { @IsString() @IsOptional() languageCode: string; @IsArray() @IsNumber({ allowNaN: false}, { each: true }) @IsOptional() stars: string[]; @IsArray() @IsOptional() keywords: string[]; @IsArray() @IsOptional() comments: string[]; }
reply.dto.ts
import { Expose, Transform, Type } from "class-transformer"; import mongoose, { Types } from "mongoose"; export class ReplyDto { @Expose({ name: '_id' }) // 确保从Mongoose对象反序列化时,ObjectId转为字符串 @Transform((value: any) => { if ('value' in value) { return value.value instanceof mongoose.Types.ObjectId ? value.value.toHexString() : value.value.toString(); } return 'unknown value'; }) public id: string; @Expose() languageCode: string; @Expose() stars: string[]; @Expose() keywords: string[]; @Expose() comments: string[]; @Expose() createdAt: Date; @Expose() updatedAt: Date; }
日志信息
控制器日志:
Path request update reply with id: 62f6df243eb6410001621b90 and body: { languageCode: 'en', keywords: [ 'hey', 'you', 'friend', 'hello' ] }
服务层日志:
Path request update reply with id: 62f6df243eb6410001621b90 and body: { languageCode: 'en', keywords: [ 'hey', 'you', 'friend', 'hello' ] }
数据库服务日志:
Path request update reply with id: 62f6df243eb6410001621b90 and body: { languageCode: 'en', keywords: [ 'hey', 'you', 'friend', 'hello' ] }
.find方法响应:
Reply updated: []
解决方案
显式转换ID类型:
Mongoose中_id字段默认是ObjectId类型,直接传入字符串ID可能无法匹配,需将字符串转为ObjectId类型后再查询:const reply = await this.replyModel.find({ _id: new mongoose.Types.ObjectId(id) });使用更合适的查询方法:
由于你是查询单个文档,推荐使用.findOne()代替.find(),它直接返回单个文档对象而非数组:const reply = await this.replyModel.findOne({ _id: new mongoose.Types.ObjectId(id) });修复DTO类型错误:
UpdateReplyDto中stars字段使用@IsNumber验证器,但类型定义为string[],存在类型不匹配问题,需改为number[]:@IsArray() @IsNumber({ allowNaN: false}, { each: true }) @IsOptional() stars: number[];
内容的提问来源于stack exchange,提问作者ytpm

