使用 Prisma + MongoDB + GraphQL 的嵌套关系返回 null

Posted

技术标签:

【中文标题】使用 Prisma + MongoDB + GraphQL 的嵌套关系返回 null【英文标题】:Nested relations returning null using Prisma + MongoDB + GraphQL 【发布时间】:2020-03-07 05:54:53 【问题描述】:

我开始将 Prisma 与 mongoDB 一起使用,在我看来,最重要的方法之一是类别和子类别之间的关系,因为尽管使用了 @relation,但子类别中并未引用该类别(链接:INLINE )。无论如何:我正在使用包含 Pet 数组的 User 集合。

我试图在我的本地服务器 (localhost:8000/graphql) 上的 Pet 文档中获取用户,但我不能,它显示为 NULL。据我所知:理论上用户不会存储在 Pet 文档(mongoDB)的一侧;因此,Prisma 在每个 User 文档中进行昂贵的搜索,将其与 Pets 数组的每个对象进行比较,但尽管如此,它还是不起作用。

在 Docker 上运行的 Prisma-server 映像(localhost:4466) 中有些东西让我很困惑,这是可能的! (获取用户并将其显示给我),而在我的本地服务器(localhost:8000/graphql)上却没有。

本地服务器(本地主机:8000/graphql): 码头上的服务器棱镜(本地主机:4466): 这是模式在 datamodel.prisma 中的外观:

type User 
    id: ID! @id
    name: String!
    email: String! @unique
    password: String!
    pets: [Pet!]! @relation(link: INLINE)
    createdAt: DateTime! @createdAt
    updatedAt: DateTime! @updatedAt

type Pet 
    id: ID! @id
    name: String!
    description: String!
    sex: String!
    owner: User
    createdAt: DateTime! @createdAt
    updatedAt: DateTime! @updatedAt

类型定义:

type Query 
   feed(where: PetWhereInput, skip: Int, first: Int, orderBy: PetOrderByInput): [Pet]!

type Mutation 
    postPet(data: PetCreateInput!): Pet   

解析器:

async function feed(parent, args, context, info) 
   return await context.prisma.pets(
      ...args
   )


async function postPet(parent, args, context, info) 
   const userId = getUserId(context) //Validate User
      return await context.prisma.createPet(
         ...args.data,
         owner:  connect:  id: userId  //Create the relationship between User and Pet
      )
   

这是数据库中的一个示例: 我还尝试将用户作为非 NULL 包含在 Pet Schema 中,但在进行查询时,我收到错误“不能为不可为空的字段 Pet.owner 返回 null。”,因为 User( owner) 没有在 mongoDB 中声明

Pet 
   ... //the others are not shown for practical purposes
   owner: User!

如果您能帮我解决这个大问题,那将很有帮助。谢谢!!

Pd:有谁知道为什么 Prism 不允许保存两个引用? UserCollection 和 PetsCollection

【问题讨论】:

【参考方案1】:

显然我犯了一个大错误!我错过了在解析器中实现这两个功能:

function pets(parent, args, context) 
   return context.prisma.user( id: parent.id ).pets()


function owner(parent, args, context) 
   return context.prisma.pet( id: parent.id ).owner() 

我们的 GraphQL 方案的这两个字段不能以相同的方式解决:Pet 中的“owner”和 User 中的“pets”。这些字段必须显式实现,因为我们的 GraphQL 服务器无法推断从何处获取该数据。

在所有者函数(解析器)中,首先使用 prisma 客户端实例获取链接,然后在其上调用“所有者”。请注意,解析器需要称为“所有者”,因为它从 schema.graphql 中的 Pet 类型解析“所有者”字段。我们可以用类似的方式解决宠物关系。

来源:https://github.com/prisma/prisma/issues/4143#issuecomment-474880883 https://www.howtographql.com/graphql-js/6-authentication/

【讨论】:

以上是关于使用 Prisma + MongoDB + GraphQL 的嵌套关系返回 null的主要内容,如果未能解决你的问题,请参考以下文章

使用 Prisma + MongoDB + GraphQL 的嵌套关系返回 null

我无法使用本地 Mongodb 使用 Prisma 启动项目

prisma.exists 方法不适用于 mongodb Atlas

prisma config connect mongodb 不要使用管理员用户

为啥我在使用 Prisma(React 应用程序)在 Mongodb 中显示和删除时遇到问题?

使用 MongoDB API 无法使用 Prisma 和 CosmosDB 进行更新