优雅而有效的方法来解决GraphQL中的相关数据

什么是解决GraphQL数据的最佳方法

这里我有一个SeekerType和JobType,JobsType嵌套在SeekerType中

搜索者可以申请许多工作.查询寻求者时,可以查询寻求者的数据,也可以查询嵌套的JobType,也可以获取jobstype数据.

但问题是如果One不查询嵌套的JobType
他不会得到乔布斯数据,但是我的搜索者解析器中的搜索器解析器也会获取该数据.

因此,在向搜索者查询提供数据时,我该如何处理,要么他只想要搜索者的详细信息,要么也可能想要工作细节.

我应该使用每个nestedType的解析器并获取父对象,并使用父对象中的字段获取相关数据???

下面的代码仅用于说明和澄清,问题是关于解决数据的最佳方法

ViewerType.js

const Viewer = new GraphQLObjectType({
    name: 'Viewer',
    fields: () => ({
        Seeker: {
            type: SeekerConnection,
            args: _.assign({
                seekerId: { type: GraphQLID },
                status: { type: GraphQLString },
                shortlisted: { type: GraphQLInt },
            }, connectionArgs),
            resolve: (obj, args, auth, rootValue) => {
                const filterArgs = getFilters(args) || {};
                return connectionFromPromisedArray(getSeekers(filterArgs), args)
                    .then((data) => {

      // getSeekers() provides all the data required for SeekerType fields and it's
          JobsType fields

                    data.args = filterArgs;
                    return data;
                }).catch(err => new Error(err));
            },
        },
    }),
});

SeekerType.js

const SeekerType = new GraphQLObjectType({
    name: 'SeekerType',
    fields: () => ({
        id: globalIdField('SeekerType', obj => obj._id),
        userId: {
            type: GraphQLID,
            resolve: obj => obj._id,
        },
        email: { type: GraphQLString },
        password: { type: GraphQLString },
        firstName: { type: GraphQLString },
        lastName: { type: GraphQLString },
        imageLink: { type: GraphQLString },
        education: { type: GraphQLString },
        address: { type: GraphQLString },
        jobs: {
            type: new GraphQLList(JobType),
        },
    }),
    interfaces: [nodeInterface],
});

getSeekers()以嵌套的方式提供完整数据作为graphql字段格式
工作领域数据也是

const getSeekers = filterArgs => new Promise((resolve, reject) => {
    if (Object.keys(filterArgs).length === 0) {
        Seeker.find(filterArgs, { password: 0 }, (err, d) => {
            if (err) return reject(err);
            return resolve(d);
        });
    } else {
        async.parallel([
            (callback) => {
                filterArgs._id = filterArgs.seekerId;
                delete filterArgs.seekerId;
                Seeker.find(filterArgs).lean()
                       .exec((err, d) => {
                    if (err) return callback(err);
                    if (err === null && d === null) return callback(null);
                    callback(null, d);
                });
            },
            (callback) => {
                filterArgs.seekerId = filterArgs._id;
                delete filterArgs._id;
                Applicant.find(filterArgs).populate('jobId').lean()
                    .exec((err, resp) => {
                    if (err) return callback(err);
                    callback(null, resp);
                });
            },
        ], (err, data) => {
            const cleanedData = {
                userData: data[0],
                userJobMap: data[1],
            };
            const result = _.reduce(cleanedData.userData, (p, c) => {
                if (c.isSeeker) {
                    const job = _.filter(cleanedData.userJobMap, 
                                 v => _.isEqual(v.seekerId, c._id));
                    const arr = [];
                    _.forEach(job, (i) => {
                        arr.push(i.jobId);
                    });
                    const t = _.assign({}, c, { jobs: arr });
                    p.push(t);
                    return p;
                }
                return reject('Not a Seekr');
            }, []);
            if (err) reject(err);
            resolve(result);

            // result have both SeekerType data and nested type 
               JobType data too.


        });
    }
});

最佳答案 我不确定我是否完全理解这个问题,但在我看来,你在一个级别上加载了导引头和工作类型信息.您应该按需加载它们.

在搜索者级别,您只能获取搜索者信息,并且您可以获取与该搜索者相关的任何记录的ID.例如,作业类型ID(如果搜索者有许多作业类型)

在作业类型级别,当用作一个搜索器的嵌套级别时,您可以使用这些ID来获取实际记录.这将使得在查询请求时按需提取作业类型.

记录提取的ID可以使用像dataloader这样的库进行缓存和批处理

点赞