4 分钟
子图最佳实践 2 - 通过使用 @derivedFrom 提高索引和查询响应性
TLDR
在你的模式中,数组可能会在条目数量超过数千时显著降低子图的性能。如果可能的话,使用数组时应使用 ‘@derivedFrom` 指令,这样可以防止大型数组的形成,简化处理器,减少单个实体的大小,显著提高索引速度和查询性能。
如何使用‘@derivedFrom’指令
你只需要在模式中的数组后面添加一个 ‘@derivedFrom’ 指令。就像这样:
1comments: [Comment!]! @derivedFrom(field: "post")
‘@derivedFrom’ 创建了高效的一对多关系,使一个实体能够根据相关实体中的字段动态地与多个相关实体关联。这种方法消除了关系双方存储重复数据的需要,使子图更加高效。
‘@derivedFrom’ 的示例用例
一个动态增长数组的例子是博客平台,其中的“Post”(帖子)可以拥有许多“Comments”(评论)。
让我们从两个实体开始,Post
(帖子)和 Comment
(评论)。
未经优化,你可以使用数组这样实现:
1type Post @entity {2 id: Bytes!3 title: String!4 content: String!5 comments: [Comment!]!6}78type Comment @entity {9 id: Bytes!10 content: String!11}
像这样的数组将在关系的“Post”(帖子)一侧有效存储额外的“Comments”(评论)数据。
以下是使用 @derivedFrom
优化版本的样子:
1type Post @entity {2 id: Bytes!3 title: String!4 content: String!5 comments: [Comment!]! @derivedFrom(field: "post")6}78type Comment @entity {9 id: Bytes!10 content: String!11 post: Post!12}
只需添加 @derivedFrom
指令,这个模式将仅在关系的“Comments”(评论)一侧存储“Comments”,而不是在“Post”(帖子)一侧。数组存储在各个单独的行中,这允许其显著扩展。如果生长没有界限,这可能导致特别大的尺寸。
这不仅能使我们的子图更加高效,而且还将解锁三个功能:
-
我们可以查询post并查看其所有评论。
-
我们可以进行反向查找,查询任何评论并查看它来自哪个帖子。
-
我们可以使用Derived Field Loaders来解锁直接访问和操纵子图映射中虚拟关系数据的能力。
结论
在子图中采用@derivedFrom
指令可以有效地处理动态增长的数组,提高索引效率和数据检索。
要了解避免大数组的更详细策略,请阅读Kevin Jones的博客:子图开发的最佳实践:避免大数组。