NestJS中使用Mongoose的.find()方法如何判断无查询结果?
如何判断
findOne查询结果是否为空? 调用this.userService.findOne(createUserDto.username)时,无法正确判断查询结果是否为空,无论输入什么,判断逻辑总是返回true或false,不符合预期。
控制器代码:
import { Get, Controller, Body, Post, Param } from "@nestjs/common"; import { RegisterService } from "./register.service"; import * as bcrypt from "bcrypt"; import { CreateUserDto } from "./create-user.dto"; @Controller("register") export class RegisterController { constructor(private userService: RegisterService) {} @Post() create(@Body() createUserDto: CreateUserDto) { let chkUname: any = this.userService.findOne(createUserDto.username); let response = { usernError: "", regOk: true, }; if (!chkUname) { // this.userService.createUser(createUserDto); return chkUname; } else { // response.usernError = "Sorry, this username is used!"; // response.regOk = false; return true; } } // create(@Param("uname") uname: any) { // return this.userService.findOne(uname); // } }
服务代码:
import { Injectable, NotFoundException } from "@nestjs/common"; import { InjectModel } from "@nestjs/mongoose"; import { Model } from "mongoose"; import { CreateUserDto } from "./create-user.dto"; import { Users, UsersDocument } from "./schema/user.schema"; @Injectable() export class RegisterService { constructor( @InjectModel(Users.name) private readonly usersModel: Model<UsersDocument> ) {} async createUser(createUserDto: CreateUserDto): Promise<UsersDocument> { const user = new this.usersModel(createUserDto); return user.save(); } async findOne(uname: string) { return this.usersModel.find({uname}).exec(); } }
问题根源及解决方法
异步逻辑未处理
服务中的findOne是异步函数(标记了async),直接赋值let chkUname: any = this.userService.findOne(...)得到的是Promise对象而非实际查询结果。Promise作为对象在布尔判断中永远为真,导致!chkUname的判断完全失效。必须用await等待异步操作完成,获取实际结果。查询方法使用错误
当前服务中用find({uname})查询,该方法返回数组,即使无匹配数据也会返回空数组[]。空数组在布尔判断中为真,因此!chkUname的逻辑完全错误。应改用findOne方法,无匹配结果时返回null,才能通过!chkUname判断是否存在用户。
修正后的代码
服务代码
import { Injectable, NotFoundException } from "@nestjs/common"; import { InjectModel } from "@nestjs/mongoose"; import { Model } from "mongoose"; import { CreateUserDto } from "./create-user.dto"; import { Users, UsersDocument } from "./schema/user.schema"; @Injectable() export class RegisterService { constructor( @InjectModel(Users.name) private readonly usersModel: Model<UsersDocument> ) {} async createUser(createUserDto: CreateUserDto): Promise<UsersDocument> { const user = new this.usersModel(createUserDto); return user.save(); } async findOne(uname: string): Promise<UsersDocument | null> { // 改用findOne,无匹配时返回null return this.usersModel.findOne({uname}).exec(); } }
控制器代码
import { Get, Controller, Body, Post, Param } from "@nestjs/common"; import { RegisterService } from "./register.service"; import * as bcrypt from "bcrypt"; import { CreateUserDto } from "./create-user.dto"; @Controller("register") export class RegisterController { constructor(private userService: RegisterService) {} // 标记为async,处理异步逻辑 @Post() async create(@Body() createUserDto: CreateUserDto) { // 用await获取实际查询结果 const chkUname = await this.userService.findOne(createUserDto.username); const response = { usernError: "", regOk: true, }; if (!chkUname) { // 无匹配用户,执行注册逻辑 await this.userService.createUser(createUserDto); return response; } else { // 用户名已存在 response.usernError = "Sorry, this username is used!"; response.regOk = false; return response; } } }
内容的提问来源于stack exchange,提问作者Alms
相关产品推荐
相关产品推荐

