最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

GraphQL关系返回null

运维笔记admin8浏览0评论

GraphQL关系返回null

GraphQL关系返回null

我正在学习graphql并使用mongodb数据库处理一个简单的API。我无法弄清楚为什么在我的架构中声明的关系不起作用:

type People {
    id:ID!
    firstName:String!
    lastName:String!
    email:String!
    serviceId:String
    apps:[String]
    service:Service
}
type Service {
    id:ID!
    name:String!
    location:String!
    peoples:[People]
}

当我运行此查询时:

query getLocationByPerson {
   People {
      firstName
      lastName
      service {
        location
      }
   }
}

这是我得到的:

"People": [
      {
        "firstName": "John",
        "lastName": "DOE",
        "service": null
      },
      {
        "firstName": "Jane",
        "lastName": "DOE",
        "service": null
      }
]

知道我在这里缺少什么吗?

回答如下:

问题出在您的解析器中:

根据您链接的回购,您的查询如下所示:

const People = require('../database/people');
const Service = require('../database/service');
const queries = {
    People: () => People.find({}),
    ...
    Service: () => Service.find({}),
    ...
  };

module.exports = queries;

People架构如下所示:

const mongoose = require('mongoose');

const Schema = mongoose.Schema;
const peopleSchema = new Schema({
    Xid: { type: String },
    firstName: { type: String },
    lastName: { type: String },
    email: { type: String },
    apps: { type: Array },
    serviceId: { type: String },
    service: { type: Schema.Types.ObjectId, ref: 'service' }
},{ versionKey: false })

module.exports = mongoose.model('people', peopleSchema);

People.find()将仅返回服务_id,但不返回整个服务对象。这就是为什么你在响应中得到null

您在People中实现的GraphQL关系有一个Service Type,而您只从服务_id返回数据库。

你有2个解决方案:

A)您在查询People时也想检索Service对象。在这种情况下,您需要使用mongoose populate函数:People: () => People.find({}).populate('service'),

以上将为People提供引用的Service对象(而不仅仅是_id)

因为你在模式中使用id而不是_id,所以上面是不够的,你需要使用以下代码,你也可以创建一个id字段来为每个服务返回

People: async () => {
      const people = await People.find({}).populate('service').exec()
      return people.map(person => ({
        ...person._doc,
        id: person._doc._id,
        service: {
          ...person._doc.service._doc,
          id: person._doc.service._doc._id,
        },
      }))
    }, return people
}

以上是非常令人沮丧的。我强烈建议采用解决方案(B)

关于populate()的文章:https://mongoosejs/docs/populate.html

B)用户使用type解析器

// Type.js
const Service = require('../database/service');
const types = {
    People: {
      // you're basically saying: In People get service field and return...
      service: ({ service }) => Service.findById(service), // service in the deconstructed params is just an id coming from the db. This param comes from the `parent` that is People
    },
   Service: {
     id: ({_id}) => _id, // because you're using id in your schema
},
  };

module.exports = queries;

关于此选项实施的说明:

  • 它是我的首选,虽然你最终需要一个dataloader来批量调用db,否则它将是非常低效的。基本上,您需要解决N + 1问题并确保有效查询数据库。这里有一篇非常好的文章:http://www.petecorey/blog/2017/08/14/batching-graphql-queries-with-dataloader/?from=east5th.co

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论