graphql:按嵌套字段排序

时间:2018-04-04 02:38:42

标签: graphql

假设我有两张桌子:
- 用户(身份证,姓名,职位)
- 帖子(id,message,user)

如何按用户名(desc)获取前10个帖子的顺序?

以下是我的架构的样子:

var PostType = new GraphQLObjectType({
  name: "Post",
  fields: () => ({
    id: { type: GraphQLInt },
    message: { type: GraphQLString },
    user: {
      type: UserType,
      args: {
        orderBy: { type: sortType }
      },
      resolve(parent, args) {
        console.info("Post resolve called.");
        return userMap[parent.user];
      }
    }
  })
});

var RootQuery = new GraphQLObjectType({
  name: "RootQueryType",
  fields: {
    allPosts: {
      type: new GraphQLList(PostType),
      resolve(parentValue, args) {
        console.info("allPosts resolve called.");
        return postData;
      }
    }
  }
});

并且查询:

{
  allPosts {
    message
    user (orderBy: {field: "name", direction: ASC}) {
      name
    }
  }
}

有什么办法,我可以在allPosts解析器功能之前调用用户解析器功能吗?因为,我试图获取按名称排序的10个用户,然后将post id传递给allPosts解析器。

1 个答案:

答案 0 :(得分:1)

GraphQL字段以自上而下的方式解析。这意味着首先解析allPosts,然后是messageuser字段(同时),然后是name字段。这必须发生,因为父母"或根字段的已解析值确定随后作为根值传递给其子字段的解析程序的值。信息来自"更高"解析器降低"降低"那些,但不是相反。

此处orderBy参数可能应该是allPosts字段而不是user字段的参数。这样做有两个原因:(1)从概念上讲,无论排序标准是什么,你都按allPostsallPosts返回的帖子进行排序 - 按惯例,将排序放在那里是有意义的; (2)user解析器可能需要参数,而不是field解析器所需的参数。

要完成上述工作,您可能需要修改识别排序条件的方式(例如,user.nameallPosts之类的路径。您可能还需要提升"将用户填充到resolve(parentValue, { sortBy: { path, direction } }) { const data = postData.map(post => { post.user = userMap[post.user] return post }); // using lodash return orderBy(data, [(post) => get(post, path)], [direction]) } 解析器的逻辑。例如:

info

可以通过解析作为第四个参数传入的+对象来确定请求中其他字段的选择集,包括参数。解析器功能。虽然这很痛苦但我不知道这个特殊情况是否真的有理由做到这一切。您可以在this answer中详细了解该方法。