Recursive/Nested/Tree hasura 中的数据获取
Recursive/Nested/Tree Data fetching in hasura
我有用户 table,它具有组织单位 table (1-1) 关系的外键,即 1 个用户属于 1 个组织单位。
我有组织单位 table,其中有列父 ID(自我引用),即组织单位可以嵌套。例如orgUnit_1 父 ID 为空,orgUnit_2 父 ID 为 1,orgUnit_3 父 ID 为 2。
orgUnit_1
- orgUnit_2
-orgUnit_3
user1 belongs to orgUnit_1
user2 belongs to orgUnit_2
user3 belongs to orgUnit_3
现在我希望,当我从 orgUnit_1 获取用户时,它也应该带上它的子 orgUnit 用户.. 即 user1、user2 和 user3。
这可能吗,在哈苏拉?
不,这是不可能的,因为 GraphQL 不支持递归查询请求。
https://github.com/graphql/graphql-spec/issues/91
你能做的最好的事情是:
org_unit {
id
name
users {
id
display_name
}
child_org_unit {
id
name
users {
id
display_name
}
child_org_unit {
id
name
users {
id
display_name
}
child_org_unit {
id
name
users {
id
display_name
}
}
}
}
}
GraphQL 不支持递归查询,但可以在 PostgreSQL 中使用递归通用 table 表达式。这可以定义为一个函数并用作 table 计算字段:
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);
跟踪 user_info
和 organization
table 并修改 table organization
并将 organization_descendant_users
作为计算字段添加到table.
示例查询:
query {
organization {
organization
organization_descendant_users {
email
}
}
}
结果:
{
"data": {
"organization": [
{
"organization": "/",
"organization_descendant_users": [
{
"email": "someone@a"
},
{
"email": "someone@a-a"
},
{
"email": "someone@b-b"
},
{
"email": "someone@top"
}
]
},
{
"organization": "/a",
"organization_descendant_users": [
{
"email": "someone@a"
},
{
"email": "someone@a-a"
}
]
},
{
"organization": "/a/a",
"organization_descendant_users": [
{
"email": "someone@a-a"
}
]
},
{
"organization": "/b",
"organization_descendant_users": [
{
"email": "someone@b-b"
}
]
},
{
"organization": "/b/a",
"organization_descendant_users": []
},
{
"organization": "/b/b",
"organization_descendant_users": [
{
"email": "someone@b-b"
}
]
}
]
}
}
我有用户 table,它具有组织单位 table (1-1) 关系的外键,即 1 个用户属于 1 个组织单位。
我有组织单位 table,其中有列父 ID(自我引用),即组织单位可以嵌套。例如orgUnit_1 父 ID 为空,orgUnit_2 父 ID 为 1,orgUnit_3 父 ID 为 2。
orgUnit_1
- orgUnit_2
-orgUnit_3
user1 belongs to orgUnit_1
user2 belongs to orgUnit_2
user3 belongs to orgUnit_3
现在我希望,当我从 orgUnit_1 获取用户时,它也应该带上它的子 orgUnit 用户.. 即 user1、user2 和 user3。
这可能吗,在哈苏拉?
不,这是不可能的,因为 GraphQL 不支持递归查询请求。
https://github.com/graphql/graphql-spec/issues/91
你能做的最好的事情是:
org_unit {
id
name
users {
id
display_name
}
child_org_unit {
id
name
users {
id
display_name
}
child_org_unit {
id
name
users {
id
display_name
}
child_org_unit {
id
name
users {
id
display_name
}
}
}
}
}
GraphQL 不支持递归查询,但可以在 PostgreSQL 中使用递归通用 table 表达式。这可以定义为一个函数并用作 table 计算字段:
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);
跟踪 user_info
和 organization
table 并修改 table organization
并将 organization_descendant_users
作为计算字段添加到table.
示例查询:
query {
organization {
organization
organization_descendant_users {
email
}
}
}
结果:
{
"data": {
"organization": [
{
"organization": "/",
"organization_descendant_users": [
{
"email": "someone@a"
},
{
"email": "someone@a-a"
},
{
"email": "someone@b-b"
},
{
"email": "someone@top"
}
]
},
{
"organization": "/a",
"organization_descendant_users": [
{
"email": "someone@a"
},
{
"email": "someone@a-a"
}
]
},
{
"organization": "/a/a",
"organization_descendant_users": [
{
"email": "someone@a-a"
}
]
},
{
"organization": "/b",
"organization_descendant_users": [
{
"email": "someone@b-b"
}
]
},
{
"organization": "/b/a",
"organization_descendant_users": []
},
{
"organization": "/b/b",
"organization_descendant_users": [
{
"email": "someone@b-b"
}
]
}
]
}
}