前言
最近刚上手NestJS,想通过NestJS与mongoDB实现一个小功能,刚上手就碰到根据主键id查询返回为空的问题。
情景再现
1. 定义了一个entity
import { Column, Entity, ObjectId, ObjectIdColumn } from "typeorm";
@Entity('appinfo')
export class AppinfoEntity {
/**
* 主键
*/
@ObjectIdColumn()
id: ObjectId;
/**
* 应用名称
*/
@Column({ length: 32 })
name: string;
/**
* 应用备注
*/
@Column({ length: 255 })
remark: string
/**
* 创建时间
*/
@Column({ type: 'timestamp', name: 'create_time', default: () => 'CURRENT_TIMESTAMP' })
createTime: Date;
/**
* 更新时间
*/
@Column({ type: 'timestamp', name: 'update_time', default: () => 'CURRENT_TIMESTAMP' })
updateTime: Date;
/**
* 创建人员id
*/
@Column()
createUserId: string;
/**
* 创建人员名称
*/
@Column({length:32})
createUserName: string;
/**
* 更新人员id
*/
@Column()
updateUserId: string;
/**
* 更新人员名称
*/
@Column({length:32})
updateUserName: string;
}
其中主键就是字段id
2. 在service中进行查询
import { HttpException, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { MongoRepository } from 'typeorm';
import { AppinfoEntity } from './appinfo.entity';
import { appinfoDto} from './dto/appInfo.dto';
import { ObjectId } from 'mongodb'
@Injectable()
export class AppinfoService {
constructor(
@InjectRepository(AppinfoEntity)
private readonly appinfoRepository: MongoRepository<AppinfoEntity>,
) { }
/**
* 根据主键查询
*/
async select(post: appinfoDto) {
const { id } = post;
console.log("id: " + id);
const appinfoEntiy = await this.appinfoRepository.findOneBy({
_id: id
})
console.log("appinfoEntiy: ", JSON.stringify(appinfoEntiy));
//注意,这里一直返回都是null
}
}
逻辑比较简单,前端传过来一个参数为id,类型为string,然后根据id去进行查询。神奇的是,一个很简单的根据主键查询,结果一直是空。 浪费了两个小时时间,总算是找到了解决方案。
解决办法
由于前端传过来的字段id为string类型,所以如果拿这个id直接去mongoDB查询,是查不出结果的,这点可以在navicat里面复现。
所以就需要把id转变成objectId类型。代码如下:
import { HttpException, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import {MongoRepository } from 'typeorm';
import { AppinfoEntity } from './appinfo.entity';
import { CreateAppinfoDto, UpdateAppinfoDto } from './dto/appInfo.dto';
import { ObjectId } from 'mongodb' //注意这个ObjectId一定要从 mongodb里面导入,而不是typeorm
@Injectable()
export class AppinfoService {
constructor(
@InjectRepository(AppinfoEntity)
private readonly appinfoRepository: MongoRepository<AppinfoEntity>,
) { }
/**
* 根据主键查询
*/
async select(post: UpdateAppinfoDto) {
const { id } = post;
console.log("id: " + id);
const appinfoEntiy = await this.appinfoRepository.findOneBy({
_id: new ObjectId(id)
})
console.log("appinfoEntiy: ", JSON.stringify(appinfoEntiy));
}
}
需要new ObjdectId(id) 方法将id转为ObjectId,就可以查询出结果。
另外注意这个ObjectId一定要从 mongodb里面导入,而不是typeorm
import { ObjectId } from 'mongodb' //注意这个ObjectId一定要从 mongodb里面导入,而不是typeorm
最后
作者刚接触typeScrpt以及nestjs,这个是暂时能找到的方法,如果你有更好的方案,欢迎评论区讨论。