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

时间:2019-02-25 13:24:17

标签: node.js mongodb mongoose graphql

我正在尝试学习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 个答案:

答案 0 :(得分:0)

问题出在创建和更新人员时设置服务属性的方式。对于嵌套类型,您要传递包含子类型的对象。现在,您只是传递给它一个字符串,因此当您尝试在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
    });
  }

}

此外,考虑到将Service对象作为大写“ 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令人困惑。但是,有很多教程和示例可以完全满足您的需求。