如何在 DTO 中定义 ObjectId 以及在 NestJS Mongoose 中获取关系数据的正确查询是啥?
Posted
技术标签:
【中文标题】如何在 DTO 中定义 ObjectId 以及在 NestJS Mongoose 中获取关系数据的正确查询是啥?【英文标题】:How to define ObjectId in DTO & what is the right query to get relational data in NestJS Mongoose?如何在 DTO 中定义 ObjectId 以及在 NestJS Mongoose 中获取关系数据的正确查询是什么? 【发布时间】:2021-02-21 04:37:58 【问题描述】:我正在使用 NestJS、Angular、GraphQL 和 MongoDB 设置应用程序,并且是这些堆栈的新手
我有 2 个名为 Tasks
和 Statuses
的集合,其中包含示例数据
任务
[
"_id":
"$oid": "5f9138f71163a739c43fc9b3"
,
"TaskDesc": "Meeting with Brian",
"StartedDate": "2020-10-22T07:42:40Z",
"EndDate": "2020-10-22T10:42:40Z",
"StatusId": "5f91375d1163a739c43fc9af"
]
状态
[
"_id":
"$oid": "5f91375d1163a739c43fc9af"
,
"StatusDesc": "Done"
]
这里是 NestJS 中定义的模式
import Schema, Types from 'mongoose';
import MongooseModule from '@nestjs/mongoose';
export const TaskSchema = new Schema(
TaskDesc: String,
StartedDate: String,
EndDate: String,
StatusId:
type: Types.ObjectId,
ref: 'Statuses'
);
export const StatusSchema = new Schema(
StatusDesc: String
);
export const SchemaGroups = MongooseModule.forFeature([
name: 'Tasks', schema: TaskSchema, collection: 'Tasks',
name: 'Statuses', schema: StatusSchema, collection: 'Statuses'
]);
DTO
import ObjectType, Field, ID from '@nestjs/graphql';
@ObjectType()
export class TasksDTO
@Field(() => ID)
id?: string;
@Field()
TaskDesc: string;
@Field()
StartedDate: string;
@Field()
EndDate: string;
@Field()
StatusId: string;
@ObjectType()
export class StatusDTO
@Field(() => ID)
readonly id?: string;
@Field()
readonly StatusDesc: string;
型号
import Document, Schema from 'mongoose';
export interface Tasks extends Document
readonly TaskDesc : string,
readonly StartedDate: string,
readonly EndDate: string,
readonly StatusId: Schema.Types.ObjectId
export interface Status extends Document
readonly StatusDesc : string
解析器
@Resolver('Tasks')
export class ListTodoResolver
constructor(private readonly todoItemsService: TodolistService)
@Query(() => [TasksDTO])
async Tasks(): Promise<TasksDTO[]>
return await this.todoItemsService.getAllTasks();
@Query(() => [StatusDTO])
async Statuses(): Promise<StatusDTO[]>
return await this.todoItemsService.getAllStatuses();
服务
import Injectable from '@nestjs/common';
import InjectModel from '@nestjs/mongoose';
import Model from 'mongoose';
@Injectable()
export class TodolistService
constructor(
@InjectModel('Tasks') private readonly todoItemsModel: Model<Tasks>,
@InjectModel('Statuses') private readonly statusItemsModel: Model<Status>
)
async getAllTasks() : Promise<Tasks[]>
let tasks = await this.todoItemsModel.find().exec(); // how should we query in the service to get relational data from another collection?
console.log(tasks);
return tasks;
async getAllStatuses() : Promise<Status[]>
return await this.statusItemsModel.find().exec();
我有这些错误
Type 'Tasks' is not assignable to type 'TasksDTO'. Types of property 'StatusId' are incompatible. Type 'ObjectId' is not assignable to type 'string'.
我们如何在 DTO 中定义 ObjectId 类型?
我对getAllTasks()
方法的预期输出是
[
"_id": "5f9138f71163a739c43fc9b3",
"TaskDesc": "Meeting with Brian",
"StartedDate": "2020-10-22T07:42:40Z",
"EndDate": "2020-10-22T10:42:40Z",
"StatusDesc": "Done"
]
【问题讨论】:
【参考方案1】:错误已经显示在哪里应该修复它。
类型“Tasks”不可分配给类型“TasksDTO”。属性“StatusId”的类型不兼容。类型“ObjectId”不可分配给类型“字符串”。
这意味着你的 DTO 应该是
@ObjectType()
export class TasksDTO
@Field(() => ID)
id?: string;
@Field()
TaskDesc: string;
@Field()
StartedDate: string;
@Field()
EndDate: string;
@Field()
StatusId: objectId; // change here
不确定 DTO 中的对象 ID 类型,尝试在文档中查找 DTO 是否有对象 ID 类型,如果没有,则应将所有位置的 StatusId 更改为字符串,这样应该可以工作
【讨论】:
以上是关于如何在 DTO 中定义 ObjectId 以及在 NestJS Mongoose 中获取关系数据的正确查询是啥?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 NestJs 框架中使用 postgres 和 sequelize 正确定义 DTO 对象
从产品展示页面谈谈Hybris系列之二: DTO, Converter和Populator
java项目中VO和DTO以及Entity,各自是在啥情况下应用的