简体   繁体   English

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

[英]Nested relations returning null using Prisma + MongoDB + GraphQL

I am starting to use Prisma with mongoDB, one of the heaviest approaches, in my opinion, are the relationships between a category and a subcategory, since the category is not referenced within the subcategory despite using the @relation (link: INLINE ).我开始将 Prisma 与 mongoDB 一起使用,在我看来,最重要的方法之一是类别和子类别之间的关系,因为尽管使用了 @relation(链接:INLINE),但子类别中并未引用该类别。 Anyway: I am using the User collection that contains a Pet array.无论如何:我正在使用包含 Pet 数组的 User 集合。

I am trying to get the User in the Pet documents on my local server (localhost:8000/graphql), but I can't, it shows me NULL.我正在尝试在本地服务器(localhost:8000/graphql)上的 Pet 文档中获取用户,但我不能,它显示了 NULL。 As far as I know: in theory the User is not stored on the side of the Pet document (mongoDB);据我所知:理论上用户不会存储在 Pet 文档(mongoDB)的一侧; and therefore Prisma makes an expensive search in each User document comparing it with each object of the Pets array, but in spite of that, it does not work.因此,Prisma 在每个用户文档中进行昂贵的搜索,将其与 Pets 数组的每个 object 进行比较,但尽管如此,它还是不起作用。

There is something that confuses me too much, in the Prisma-server image(localhost:4466) that runs on Docker is POSSIBLE,: (gets the User and shows it to me).在 Docker 上运行的 Prisma 服务器映像(localhost:4466)中,有一些事情让我很困惑,是可能的,:(获取用户并将其显示给我)。 while on my local server (localhost:8000/graphql) it doesn't.而在我的本地服务器(localhost:8000/graphql)上却没有。

LOCAL SERVER (localhost:8000/graphql):本地服务器(本地主机:8000/graphql):
本地主机:8000/graphql
SERVER PRISMA ON DOCKER (localhost:4466): Z469A31FD9D773110F14057BAECCDDD25Z(本地主机:4466)上的服务器棱镜:
本地主机:4466
This is how schemas look in datamodel.prisma:这是模式在 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
}


typeDefs:类型定义:

type Query {
   feed(where: PetWhereInput, skip: Int, first: Int, orderBy: PetOrderByInput): [Pet]!
}
type Mutation {
    postPet(data: PetCreateInput!): Pet   
}

Resolvers:解析器:

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
      })
   }

Here is an example in the DB:这是数据库中的一个示例:
在此处输入图像描述
I have also tried to include the User as a non-NULL in the Pet Schema, but at the time of making the query, I get an error "Cannot return null for non-nullable field Pet.owner.", because the User(owner) does not is declared in mongoDB我还尝试将用户作为非 NULL 包含在 Pet Schema 中,但在进行查询时,我收到错误“无法为不可为空的字段 Pet.owner 返回 null。”,因为用户(所有者)没有在 mongoDB 中声明

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

It would be helpful if you can help me with this big problem.如果您能帮助我解决这个大问题,那将很有帮助。 Thank you!!谢谢!!

Pd: Does anyone know why Prism does not allow saving both references? Pd:有谁知道为什么 Prism 不允许保存两个引用? UserCollection and PetsCollection UserCollection 和 PetsCollection

Apparently I made a big mistake: I missed implementing these two functions in the Resolvers:显然我犯了一个大错误:我错过了在解析器中实现这两个功能:

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() 
}

These two fields of our GraphQL scheme that cannot be solved in the same way: "owner" in Pet and "pets" in User.我们的 GraphQL 方案的这两个字段不能以相同的方式解决:Pet 中的“owner”和 User 中的“pets”。 These fields must be explicitly implemented because our GraphQL server cannot infer where to get that data.这些字段必须明确实现,因为我们的 GraphQL 服务器无法推断从何处获取该数据。

In the owner function (resolver), first are fetching the Link using the prisma client instance and then invoke "owner" on it.在所有者 function(解析器)中,首先使用 prisma 客户端实例获取链接,然后在其上调用“所有者”。 Notice that the resolver needs to be called "owner" because it resolves the "owner" field from the Pet type in schema.graphql.请注意,解析器需要称为“所有者”,因为它从 schema.graphql 中的 Pet 类型解析“所有者”字段。 We can resolve the pets relation in a similar way.我们可以用类似的方式解决宠物关系。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM