【Nestjs学习日记】Schema 的 Ref

作者: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的详细数据。

相关推荐
hhw19911223 分钟前
vue总结
前端·javascript·vue.js
学习2年半25 分钟前
汇丰eee2
前端·spring
代码续发26 分钟前
Vue进行前端开发流程
前端·vue.js
zpjing~.~30 分钟前
CSS &符号
前端·css
冴羽1 小时前
SvelteKit 最新中文文档教程(19)—— 最佳实践之身份认证
前端·javascript·svelte
拉不动的猪1 小时前
ES2024 新增的数组方法groupBy
前端·javascript·面试
huangkaihao1 小时前
单元测试 —— 用Vitest解锁前端可靠性
前端
archko2 小时前
telophoto源码查看记录
java·服务器·前端
倒霉男孩2 小时前
HTML5元素
前端·html·html5
柯南二号2 小时前
CSS 学习提升网站或者项目
前端·css