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

相关推荐
AALoveTouch12 小时前
大麦网协议分析
javascript·python
●VON12 小时前
React Native for OpenHarmony:2048 小游戏的开发与跨平台适配实践
javascript·学习·react native·react.js·von
木斯佳13 小时前
前端八股文面经大全:26届秋招滴滴校招前端一面面经-事件循环题解析
前端·状态模式
光影少年13 小时前
react状态管理都有哪些及优缺点和应用场景
前端·react.js·前端框架
晚烛14 小时前
CANN + 物理信息神经网络(PINNs):求解偏微分方程的新范式
javascript·人工智能·flutter·html·零售
saber_andlibert14 小时前
TCMalloc底层实现
java·前端·网络
逍遥德14 小时前
如何学编程之01.理论篇.如何通过阅读代码来提高自己的编程能力?
前端·后端·程序人生·重构·软件构建·代码规范
冻感糕人~14 小时前
【珍藏必备】ReAct框架实战指南:从零开始构建AI智能体,让大模型学会思考与行动
java·前端·人工智能·react.js·大模型·就业·大模型学习
程序员agions15 小时前
2026年,“配置工程师“终于死绝了
前端·程序人生
alice--小文子15 小时前
cursor-mcp工具使用
java·服务器·前端