首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在GraphQL中对递归数据结构建模

如何在GraphQL中对递归数据结构建模
EN

Stack Overflow用户
提问于 2017-06-25 21:38:39
回答 2查看 19.4K关注 0票数 32

我有一个树数据结构,我想通过一个GraphQL接口返回它。

这个结构并不是特别大(小到不会在一次调用中返回它是个问题)。

未设置结构的最大深度。

我已经将该结构建模为如下所示:

代码语言:javascript
复制
type Tag{
    id: String!
    children: [Tag]
}

当一个人想要获得任意深度的标签时,问题就出现了。

要使所有的子节点都达到(例如)级别3,需要编写一个查询,如下所示:

代码语言:javascript
复制
`{       tags {           id          children {               id               children {                   id               }          }       }    }` 

有没有一种方法可以编写一个查询来返回任意深度的所有标签?

如果不是,那么在GraphQL应用程序接口中对类似上面的结构建模的推荐方法是什么。

EN

回答 2

Stack Overflow用户

发布于 2018-09-07 18:20:58

不久前,我想出了另一个解决方案,就像@WuDo建议的方法一样。

其思想是在数据层上使用is来引用树(每个子节点都有它的父节点)并标记树的根,然后在客户端递归地构建树。

这样,您就不必担心限制查询的深度,就像@samcorcos的答案一样。

模式:

代码语言:javascript
复制
type Query {
    tags: [Tag]
}

type Tag {
    id: ID!
    children: [ID]
    root: Boolean
}

响应:

代码语言:javascript
复制
{ 
    "tags": [
        {"id": "1", "children": ["2"], "root": true}, 
        {"id": "2", "children": [], "root": false}
    ] 
}

客户端树构建:

代码语言:javascript
复制
import find from 'lodash/find';
import isArray from 'lodash/isArray';

const rootTags = [...tags.map(obj => {...obj)}.filter(tag => tag.root === true)];
const mapChildren = childId => {
    const tag = find(tags, tag => tag.id === childId) || null;

    if (isArray(tag.children) && tag.children.length > 0) {
        tag.children = tag.children.map(mapChildren).filter(tag => tag !== null);
    }
}
const tagTree = rootTags.map(tag => {
    tag.children = tag.children.map(mapChildren).filter(tag => tag !== null);
    return tag;
});
票数 28
EN

Stack Overflow用户

发布于 2022-01-24 15:53:17

如果您愿意放弃GraphQL提供的类型安全和子字段查询以及通过is缓存和引用对象的能力,另一种选择是将数据编码为JSON。gaphql-type-json包提供了解析器来简化这一过程。这些也包含在graphql-scalars的许可下,它包含了许多其他方便的标量。

我这样做是为了定义动态表单控件的分层数据。在这种情况下,没有任何it可丢失,因此很容易获胜。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44746923

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档