GraphQL 简单嵌套查询返回空字段

Posted

技术标签:

【中文标题】GraphQL 简单嵌套查询返回空字段【英文标题】:GraphQL simple nested query returning null field 【发布时间】:2019-07-18 22:02:07 【问题描述】:

我正在尝试学习 GraphQL(& node.js & MongoDB 等)。我无法让这个简单的嵌套查询返回结果:

query getLocationByPerson 
   People 
      firstName
        lastName
        service 
        location
      
   

我得到的结果是:


  "data": 
    "People": [
      
        "firstName": "John",
        "lastName": "DOE",
        "service": null
      
    ]
  ,
  "errors": [
    
      "message": "Cannot return null for non-nullable field Service.location.",
      "locations": [
        
          "line": 6,
          "column": 7
        
      ],
      "path": [
        "People",
        0,
        "service",
        "location"
      ]
    
  ]

所有代码都可以在这里找到:https://github.com/fabricezerrouki/graphql-playground 谁能看看并帮助我弄清楚我做错了什么? 谢谢。

【问题讨论】:

【参考方案1】:

问题在于您在创建和更新人员时设置服务属性的方式。对于嵌套类型,您希望传递一个包含子类型的对象。现在您只传递一个字符串,因此当您尝试在 createPerson 解析器中将 Service 设置为等于 args.serviceId 时,它不存在,因此在 MongoDB 中将该字段的值设置为 null。像这样重构:

在 index.js 中

type Mutation 
  createPerson(Xid: String!, firstName: String */ ... */ service:  id: ID!, name: String!, location: String! ): People!

在 /resolvers/Mutation.js 中

const Mutations = 

  createPerson: async (parent, args) => 
    const newPerson = new People(
      Xid: args.Xid,
      firstName: args.firstName
      /* and so on... */
      Service: args.service.id
    );
  


此外,鉴于您将服务对象作为大写“S”服务保存到 MongoDB 的方式,而查询中的变量是小写“s”服务,您将来可能会遇到问题。每次搜索数据库时,您都必须记住现在直接将 args.service 解构到您的 Model.find(service) 方法中。有点小众问题,但我自己也遇到过这个问题,所以想我会提到它。

根据 OP 评论编辑

是的,可以执行 SQL 连接链接操作来返回带有 Person 查询的 Service 对象,但您需要在查询解析器中执行此操作,并且只需在突变期间存储 Service id。在这种情况下,我猜它为 null 的原因是您调用 args.serviceId 但 createPerson() 参数只是“服务”,因此请尝试将 Mutation.js 更改为 Service: args.service

至于实际的连接操作,这有点复杂。我建议首先返回 serviceId 字符串以确保它正常工作。然后你需要深入研究 MongoDB aggregation pipeline。更具体地说,$lookup pipeline operator 执行类似于 SQL 连接的功能。每次我必须处理聚合管道时,我都会把头撞到墙上。这是一个非常高级的主题,IMO 语法令人困惑。但是有很多教程和示例可以完全按照您的意愿去做。

【讨论】:

谢谢。实际上我有两个 mongoDB 集合:“peoples”和“services”。在每个人的文档中,我都有一个与服务文档“_id”匹配的“服务”objectId。我会以某种方式使用它,就像 SQL 连接一样。可能吗?您需要 mongodb 集合的屏幕截图吗? 查看我的编辑,如果您还有其他问题,请告诉我 再次感谢。需要明确的是: createPerson 突变工作得很好,问题仅在于我之前发布的嵌套查询。当我按照您的建议进行更新时,“服务”字段现在为空。我只是尝试返回服务的“id”而不是位置字段,结果仍然是“null”。 我想我有点困惑,我看到 index.js 第 37 行中的输入是“service”,但在 Mutation.js 第 11 行中它被作为“serviceId”访问。如果它没坏,我想。尝试一些故障排除并查看您得到的结果:从服务类型定义中删除 bang(!),以便不再需要它们。这将消除错误,因此您可以看到实际发回的内容。此外,console.log Query.js 第 5 行中 Service.findByID(service) 的结果,以确保没有异步函数返回承诺而不是完全解析。 感谢您的帮助,我使用最后一次修改更新了存储库,但仍然无法正常工作:(

以上是关于GraphQL 简单嵌套查询返回空字段的主要内容,如果未能解决你的问题,请参考以下文章

使用数组作为 GraphQL 查询的变量

具有多个嵌套解析器并将字段映射到参数的 GraphQL 查询

为啥我的 graphql 嵌套查询返回 null?

有没有办法将 GraphQL 查询字段分组到子/嵌套查询组中?

GraphQL 嵌套查询返回 null

具有嵌套字段类型条件的 Apollo graphql 查询