【问题标题】:GraphQL simple nested query returning null fieldGraphQL 简单嵌套查询返回空字段
【发布时间】: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 谁能看看并帮助我弄清楚我做错了什么? 谢谢。

【问题讨论】:

    标签: node.js mongodb mongoose graphql


    【解决方案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) 的结果,以确保没有异步函数返回承诺而不是完全解析。
    • 感谢您的帮助,我使用最后一次修改更新了存储库,但仍然无法正常工作:(
    猜你喜欢
    • 2019-07-08
    • 2020-01-15
    • 2020-02-25
    • 2019-12-20
    • 2019-08-12
    • 1970-01-01
    • 2017-10-01
    • 2021-01-29
    相关资源
    最近更新 更多