作者:markzzw 时间:2024-2-26
线上代码:CodeSandbox
Github:zhangzewei/nest-learning-tutorial
系列阅读 【Nestjs学习日记】专栏
在 mongoDB 的 Schema 中,可以将字段定义为另一个数据表中的数据的 ObjectId,很多情况会用到,例如:cat 表中的 foods 应该为另一个 foods 表中的数据,这样就不用每次都填入字符串,而是在 foods 表中的数据挑选,也方便在 UI 界面中进行多选的操作。
新建 Food Module
1. food.module.ts
ts
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { Food, FoodSchema } from './food.schema';
import { FoodController } from './food.controller';
import { FoodService } from './food.service';
@Module({
imports: [
MongooseModule.forFeature([{
name: Food.name,
schema: FoodSchema
}])
],
controllers: [FoodController],
providers: [FoodService],
exports: [FoodService]
})
export class FoodModule { }
2. food.schema.ts
ts
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { HydratedDocument } from 'mongoose';
export type FoodDocument = HydratedDocument<Food>;
@Schema()
export class Food {
@Prop()
name: string;
@Prop()
brand: string;
}
export const FoodSchema = SchemaFactory.createForClass(Food);
3. food.servicets
ts
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { CreateFoodDto } from './food.dto';
import { Food } from './food.schema';
@Injectable()
export class FoodService {
isChanged = false;
constructor(
@InjectModel(Food.name) private foodModel: Model<Food>
) { }
async findAll() {
return this.foodModel.find();
}
async create(createFoodDto: CreateFoodDto) {
const createdCat = new this.foodModel(createFoodDto);
return createdCat.save();
}
}
4. food.controller.ts
ts
import { Controller, Get, Body, Post, Param, Put } from '@nestjs/common';
import { CreateFoodDto } from './food.dto';
import { FoodService } from './food.service';
@Controller('food')
export class FoodController {
constructor(
private foodService: FoodService
) { }
@Get()
findAll() {
return this.foodService.findAll();
}
@Post()
createCat(@Body() body: CreateFoodDto) {
return this.foodService.create(body);
}
}
5. food.dto.ts
ts
import { IsString, IsNumber, IsArray } from 'class-validator';
import { PartialType } from '@nestjs/mapped-types';
export class CreateFoodDto {
@IsString()
name: string;
@IsString()
brand: string;
}
export class UpdateFoodDto extends PartialType(CreateFoodDto) { }
录入food数据
修改 cat scheme 的 foods 的描述
可以看到这里的类型为引用,引用的值为 foods 表中的 objectId,所以接下来调用 postman 的 cat post 请求,其中 foods 的值为 food 的 _id。
数据库中的 cats 的foods数据是 objectId
验证
修改 cat service 中的 findAll 函数。
ts
async findAll() {
const cats = await this.catModel.find();
const foods = await this.foodService.findAll();
cats.map(cat => {
const newFoods = cat.foods.map(fid =>
foods.find(fd =>
fd.id.toString() === fid.toString()
)
);
cat.foods = newFoods;
return cat;
});
return cats;
}
这样就能够通过food id获取到对应的food的详细数据。