我正在尝试学习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 谁能看看并帮助我弄清楚我在做什么错? 谢谢。
答案 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})方法。有点小众问题,但我本人就遇到了这个确切的问题,所以想出了。
是的,可以执行SQL连接链接操作以返回带有Person查询的Service对象,但是您需要在查询解析器中返回该对象,并且只需在突变期间存储Service id。在那种情况下,我猜它为null的原因是您在调用args.serviceId
,但是createPerson()参数只是“服务”,因此请尝试将Mutation.js更改为Service: args.service
。
对于实际的联接操作,这有点复杂。我建议先返回serviceId字符串以确保其正常工作。然后,您需要深入研究MongoDB aggregation pipeline。更具体地说,$lookup pipeline operator执行类似于SQL连接的功能。每当我不得不处理聚合管道时,我都会把头撞在墙上。这是一个相当高级的主题,其语法IMO令人困惑。但是,有很多教程和示例可以完全满足您的需求。