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

相关推荐
程序猿阿伟8 分钟前
《3D动作游戏受击反馈:从模板化硬直到沉浸式打击感的开发拆解》
前端·网络·3d
jsonchao11 分钟前
web 菜鸟级选手,纯好玩,做了 1 个小游戏网站(我感觉挺好玩😂)
前端
Onion12 分钟前
解决 iframe 中鼠标事件丢失问题:拖拽功能的完整解决方案
前端·javascript·vue.js
Sailing12 分钟前
🔥🔥「别再复制正则了」用 regex-center 一站式管理、校验、提取所有正则
前端·javascript·面试
GISer_Jing23 分钟前
前端知识详解——HTML/CSS/Javascript/ES5+/Typescript篇/算法篇
前端·javascript·面试
一枚前端小能手23 分钟前
🔧 jQuery那些经典方法,还值得学吗?优势与式微的真相一次讲透
前端·javascript·jquery
写不来代码的草莓熊26 分钟前
vue前端面试题——记录一次面试当中遇到的题(4)
前端·javascript·vue.js·面试
Ratten31 分钟前
【uniapp】---- 在 uniapp 实现 app 的版本检查、下载最新版本、自动安装
前端
立方世界39 分钟前
HTML编写规则及性能优化深度解析:从基础到企业级实践
前端·性能优化·html
JarvanMo1 小时前
请停止用 Java 习惯来破坏你的 Flutter 代码
前端