【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的详细数据。

相关推荐
小李子呢02115 小时前
前端八股CSS(2)---动画的实现方式
前端·javascript
GreenTea6 小时前
从 Claw-Code 看 AI 驱动的大型项目开发:2 人 + 10 个自治 Agent 如何产出 48K 行 Rust 代码
前端·人工智能·后端
渣渣xiong7 小时前
从零开始:前端转型AI agent直到就业第五天-第十一天
前端·人工智能
布局呆星7 小时前
Vue3 | 组件通信学习小结
前端·vue.js
C澒7 小时前
IntelliPro 企业级产研协作平台:前端智能生产模块设计与落地
前端·ai编程
OpenTiny社区9 小时前
重磅预告|OpenTiny 亮相 QCon 北京,共话生成式 UI 最新技术思考
前端·开源·ai编程
前端老实人灬9 小时前
web前端面试题
前端
Moment9 小时前
AI 全栈指南:NestJs 中的 Service Provider 和 Module
前端·后端·面试
IT_陈寒9 小时前
为什么我的JavaScript异步回调总是乱序执行?
前端·人工智能·后端