GraphQL查询中的数据规范化

时间:2020-04-30 15:00:40

标签: graphql database-normalization

我正在使用GraphQL查询具有两种数据类型的数据库:UserGroup

组具有字段users,该字段是该组中User个对象的数组。我在根groups处有一个字段,该字段返回我所有组的数组。

一个典型的查询可能看起来像这样:

{
    groups {
        id,
        name,
        users {
            id,
            name,
            address,
            email,
            phone,
            attitude,
            job,
            favoriteQuote,
            favoriteColor,
            birthday
        }
    }
}

问题在于,这些用户中有很多可以属于多个组,并且User有很多字段,这会使响应变得很大。

是否有办法为对象的第一个实例获取一组字段,并为响应中的其他每个实例获取一组不同的字段?

在响应中,每个用户只需要一次namejobemail等,之后只需id(此后我可以进行自己的归一化)

或者

是否有任何方法只能为组中的所有用户获取id字段,并返回查询中已引用的所有唯一User对象的单独数组(不是< em> all User个对象)?

2 个答案:

答案 0 :(得分:2)

是否有任何方法可以为对象的第一个实例获取一组字段,并为响应中的其他每个实例获取一组不同的字段?

不。除非单个项目的类型不同,否则将为列表中的每个项目返回相同的字段集,因为可以为运行时返回的每种类型指定单独的选择集。

是否可以仅获取组中所有用户的id字段,并返回查询中已引用的所有唯一User对象(不是所有User对象)的单独数组?

您可以设计您的架构来适应这一点。像

{
  groups {
    nodes {
      id
      name
      users {
        id
      }
    }
    uniqueUsers {
      id
      # other fields
    }
  }
}

您的groups解析器将需要处理所有规范化并以适当的形状返回数据。但是,一个更简单的解决方案可能就是反转您的关系:

{
  users {
    id
    name
    address
    email
    phone
    attitude
    job
    favoriteQuote
    favoriteColor
    birthday
    groups {
      id
      name
    }
  }
}

答案 1 :(得分:1)

通常-通常

...归一化...当然...使用apollo及其归一化缓存。

从API返回的所有记录必须具有相同的形状。

您可以仅通过查询ID和名称(完整/分页)来获取数据并渲染某些<MembersList/>组件。

稍后,您可以使用自己的查询(位于内部的钩子<UserProfile/>中,在某些useQuery组件中呈现详细信息,以从缓存/ api中获取其他数据(可控)。

您的特定要求-可能

第一个选项:

通常,响应是一种常见的形式(根据要求),但是您可以在解析器级别决定返回什么。这需要更改查询结构,以允许(API,后端)对某些属性进行空值化。

group {
    id
    name
    users {
        id
        name
        profile {
          photo
          email
          address

使用profile自定义json类型...您可以构造用户解析器,以仅返回第一条记录的完整数据,并返回所有后续用户的null

第二个选项:

您可以在一个请求中使用2个稍有不同的查询。简而言之,使用别名(请参阅文档):

groupWithFullMember: group ( groupId:xxx, limitUsers:1 ) {
    id
    name
    users {
        id
        name
        address
        email
        ...
    }
}

groupMembers: group ( groupId:xxx ) {
    id
    name // not required
    users {
        id
        name
    }
}

组解析器可以返回其子级users ...或users解析器可以访问limitUsers参数以限制响应/修改数据库查询。

相关问题