GraphQL 如何使用 Nestjs 或 type-graphql 设置查询 MongoDB ref 集合

Posted

技术标签:

【中文标题】GraphQL 如何使用 Nestjs 或 type-graphql 设置查询 MongoDB ref 集合【英文标题】:GraphQL how to setup query the MongoDB ref collection using Nestjs or type-graphql 【发布时间】:2020-06-27 04:45:28 【问题描述】:

我对如何使用 GraphQL 查询 mongodb 中的 ref 集合有疑问。 我有两个系列:People 和 Cat。人们将拥有零或一只猫,而猫将属于一个人。

首先,我使用graphql创建一个People,然后复制返回的People的ID。

接下来,我将那个人的 ID 传递给 CreateCatService 来创建一只猫,这样这个创建的猫就属于之前创建的人了。

现在的问题是我无法查询 ref(嵌套)集合的数据。

mutation 
  createCat(
    input: 
      name: "my cat"
      age: 1
      breed: "test"
      people: "5e6edf120e27eb369db9ceaa" <----- People's id
    
  ) 
    id
    name
    people 
      name <--- return null ???
    
  

如果我查询猫,嵌套的人为空,它显示错误:"message": "ID cannot represent value: &lt;Buffer 5e 6e df


  cats 
    name
    people 
      id
    
  

下面是我的架构和代码生成 typedef。

export const PeopleSchema = new mongoose.Schema(
  name: String,
  cat: type: mongoose.SchemaTypes.ObjectId, ref: "Cat"
)
export const CatSchema = new mongoose.Schema(
  name: String,
  age: Number,
  breed: String,
  people: type: mongoose.Schema.Types.ObjectId, ref: 'People'
);
@ObjectType()
export class PeopleType 
  @Field(() => ID)
  id: string;

  @Field()
  name: string;

  @Field(type => CatType,  nullable: true )
  cat?: CatType

@ObjectType()
export class CatType 
  @Field(() => ID)
  id: string;

  @Field()
  readonly name: string;

  @Field(() => Int)
  readonly age: number;

  @Field()
  readonly breed: string;

  @Field(type => PeopleType, nullable: true)
  readonly people?: PeopleType;

我的猫输入:

@InputType()
export class CatInput 
  @Field()
  readonly name: string;

  @Field(() => Int)
  readonly age: number;

  @Field()
  readonly breed: string;

  @Field()
  readonly people: string; // this will be the people's id

我的 CreateCatService

  async create(createCatDto: CatInput): Promise<Cat> 
    const createdCat = new this.catModel(createCatDto);
    return await createdCat.save();

我的 CatResolver

  @Mutation(() => CatType)
  async createCat(@Args('input') input: CatInput) 
    return this.catsService.create(input);

【问题讨论】:

【参考方案1】:

在尝试了很多更改后,我发现问题是我没有填充子集合。在 CatResolver 中,我需要这样做,而不是返回 createdCat.save();

    const savedCat = await createdCat.save();
    return await savedCat.populate('people').execPopulate();

【讨论】:

【参考方案2】:

我认为问题在于您的解析器不知道如何解析 ObjectType 中的人。您需要在您的 Resolver 类中创建一个 FieldResolver。

见:https://github.com/MichalLytek/type-graphql/blob/master/docs/resolvers.md#field-resolvers

基本上,在您的 CatResolver 中,您需要一个 FieldResolver 类型的方法 people,这应该注入 PeopleType(此处不确定:阅读文章)

  @FieldResolver()
  people(@Root() people: People) 
    // then using the people id in root, get the people detail from People.
  

【讨论】:

以上是关于GraphQL 如何使用 Nestjs 或 type-graphql 设置查询 MongoDB ref 集合的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 NestJS GraphQL 实现 NuxtJS Apollo

如何使用 nestjs-graphql-fastify 服务器上传文件以及如何测试此类功能?

nestjs 将接口转换为 graphql 类

如何使用 GRAPHQL 测试 e2e Nestjs API

使用@nestjs/graphql 使用@ResolveProperty 和@Resolvers 创建嵌套查询

如何在nestjs graphql中实现用户保护