hasura 中的递归/嵌套/树数据获取

oOX*_*Aam 1 postgresql graphql hasura

我有用户表,它具有与组织单位表 (1-1) 关系的外键,即 1 个用户属于 1 个组织单位。

我有一个组织单元表,其中包含列父 ID(自引用),即组织单元可以嵌套。例如,orgUnit_1 的 parent-id 为 null,orgUnit_2 的 parent-id 为 1,orgUnit_3 的 parent-id 为 2。

orgUnit_1
    - orgUnit_2
        -orgUnit_3

user1 belongs to orgUnit_1
user2 belongs to orgUnit_2
user3 belongs to orgUnit_3
Run Code Online (Sandbox Code Playgroud)

现在我希望,当我从 orgUnit_1 获取用户时,它还应该带上它的子 orgUnit 用户......即 user1、user2 和 user3。

这可能吗,在hasura?

San*_*ahn 5

GraphQL 不支持递归查询,但可以在 PostgreSQL 中使用递归公用表表达式。这可以定义为一个函数并用作表计算域:

drop function if exists organization_descendant_users(organization);
drop table if exists user_info;
drop table if exists organization;

create table organization (
    id serial primary key,
    parent int references organization(id),
    organization text not null
);

insert into organization(id, parent, organization)
values
    (1, null, '/'),
    (2, 1, '/a'),
    (3, 2, '/a/a'),
    (4, 1, '/b'),
    (5, 4, '/b/a'),
    (6, 4, '/b/b');

alter sequence organization_id_seq restart with 7;

create table user_info (
    id serial primary key,
    email text unique,
    organization int not null references organization(id)
);

insert into user_info (id, email, organization)
values
    (1, 'someone@a-a', 3),
    (2, 'someone@b-b', 6),
    (3, 'someone@a', 2),
    (4, 'someone@top', 1);

alter sequence user_info_id_seq restart with 5;

create function organization_descendant_users(organization_row organization)
returns setof user_info as $$
with recursive organization_descendant as (
    select
        id,
        id as descendant
    from organization
    union all
    select
        o.parent as id,
        n.descendant
    from organization o
    join organization_descendant n on n.id = o.id
)
select user_info.*
from organization_descendant
join user_info on user_info.organization = organization_descendant.descendant
where organization_descendant.id is not null and organization_descendant.id = organization_row.id
order by email;
$$ language sql stable;

create index on organization(parent);
create index on user_info(organization);
Run Code Online (Sandbox Code Playgroud)

跟踪user_infoorganization表并修改表organization并将其添加organization_descendant_users为表上的计算字段。

示例查询:

query {
  organization {
    organization
    organization_descendant_users {
      email
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

结果:

query {
  organization {
    organization
    organization_descendant_users {
      email
    }
  }
}
Run Code Online (Sandbox Code Playgroud)