查询复杂度
管理查询的复杂度以提高性能并防止错误响应。
何时查询太复杂?
我们有很多版本,每个版本都有数千个图标,而且大多数图标都可以在几种 familyStyles 中使用。因此,可查询的内容远超单个查询允许的范围。
如果您的查询过于复杂,您将收到一个错误响应,解释了查询中过于复杂的部分。您需要修改查询以选择更少的内容。您可以发出多个较不复杂的查询,而不是发出一个过于复杂的单个查询。
100,000
是单个查询允许的最大复杂度。
例如,此查询过于复杂
query{ release(version: "6.4.2") { icons { id unicode svgs(filter: {familyStyles: [ {family:CLASSIC, style:SOLID}, {family:CLASSIC, style:LIGHT}, {family:CLASSIC, style:REGULAR} ]}) { width height pathData html } } }}
它选择 Font Awesome 6.4.2 中的所有图标。对于每个图标,它获取 id
和 unicode
字段,以及三种 familySyles 的 svgs
:Classic Solid、Classic Light 和 Classic Regular。对于每个 SVG,它选择四个字段。
让我们看看为什么它过于复杂。
计算查询复杂度的基本经验法则是在考虑某些字段(如 icons
或 svgs
表示多个)的情况下,为每个选定的字段计数 1
。
自下而上
正在为 svgs
选择三种 familyStyles,因此该字段的乘数为 3
。并且在 svgs
下选择了 4
个字段。这意味着 svgs
字段的复杂度将为每个图标的 3 * 4 == 12
。
每个图标还具有 id
和 unicode
。因此,每个图标的复杂度为 14
(svgs
的 12
,加上其他 2
)。
Font Awesome 6.4.2 中有 3,690
个图标 ID;因此,这是 Font Awesome 6.4.2 的 icons
字段的乘数。
Font Awesome 的其他版本将具有不同的图标数量。有关显示版本中包含多少个图标 ID 的查询,请参见下面的 计算图标 ID 与计算图标。
因此,此查询中的 icons
字段的复杂度将为 51,660
。
release
字段只计为 1
。
因此,查询的总复杂度为 51,661
。
由于查询允许的最大复杂度为 50,000
,因此您使用此查询时看到的错误如下所示
{ "errors": [ { "locations": [ { "column": 3, "line": 3 } ], "message": "Field icons is too complex: complexity is 51,660 and maximum is 50,000" }, { "locations": [ { "column": 2, "line": 2 } ], "message": "Field release is too complex: complexity is 51661 and maximum is 50,000" }, { "locations": [ { "column": 1, "line": 1 } ], "message": "Operation is too complex: complexity is 51661 and maximum is 50,000" } ]}
在这种情况下,只需从 svgs
字段的 filter
中删除一个 familyStyles 即可使其复杂度大大降低。
计算图标 ID 与计算图标
选择 icons
字段将选择特定 Font Awesome 版本中所有图标 ID。icons
的每个项目都有一个 id
字段,它是给定 Font Awesome 版本中图标集中唯一的名称。
例如,有一个名为 avocado
的图标,截至 Font Awesome 6.4.2,它在 8 种不同的 familyStyles 中可用。因此,这算作 8 个图标,但仅算作 1 个图标 ID。
该图标 ID 的某些属性无论 familyStyle 如何都保持不变。请参见 Icon
对象上的各种字段。例如,它的 unicode
或 label
。
因此,对应于 icons
字段的复杂度乘数是版本中图标 ID 的数量,而不是图标的总数。
例如,在 Font Awesome 6.4.2 中,有
- 3,690 个图标 ID
- 24,208 个图标
以下查询为您提供了版本的这两个计数
query { release(version:"6.4.2") { iconCount{ pro } iconIdCount{ pro } }}
有 24,208 个图标,因为大多数图标 ID 在与 avocado 相同的 8 种 familyStyles 中可用。那么为什么不是 3,690 个图标 ID 乘以 8 种 familyStyles 的总数 29,520?为什么有 24,208 个图标,而不是 29,520?因为某些图标 ID 仅存在于 Classic Brands familyStyle 中。
有 473 个图标 ID 存在于 brands familyStyle 中,其中大多数仅在该 familyStyle 中可用。但更复杂的是,其中只有少数几个同时存在于 Classic Brands 和其他 8 种 familyStyles 中。
因此,结果表明 Font Awesome 6.4.2 中有 24,208 个不同的图标。
安全起见
如果您的查询选择某些版本中所有图标的 SVG,那么安全的选择是在 svgs
字段上使用 filter
来一次仅选择一种 familyStyle。如果您的应用程序需要三种不同的 familyStyles,那么发出三个单独的查询,每个查询选择其中一个 familyStyles。
例如,以下查询的复杂度仅为 22,141
,它为您提供渲染 Font Awesome 6.4.2 中一种 familyStyle 中所有 SVG 图标所需的一切
query { release(version:"6.4.2") { icons { id svgs(filter:{familyStyles:[ {family: SHARP, style: LIGHT}, ]}) { familyStyle { prefix } width height pathData } } }}
您可以使用上述查询中的 iconIdCount { pro }
值作为 icons
字段的乘数 (3,690),并将该值乘以 icons
下选择的字段数量(6)。即 22,140。为顶层的 release
字段添加 1,您将得到总数 22,141。
如果您将过滤器更改为使用任何其他单一 familyStyle,它将具有相同的复杂度。
因此,如果您的应用程序需要,您可以在三种不同的 familyStyles 中运行三次相同的查询,并确信复杂度将远低于限制。
即使在 Font Awesome 的后续版本中 iconIdCount
翻倍,此相同的查询也仍然将在限制范围内。
恒定复杂度与可变复杂度
对任何给定版本的 Font Awesome 的复杂度计算都是稳定的。Font Awesome 6.4.2 有 3,690 个图标 ID 和 9 种 familyStyles。这不会改变。因此,基于这些乘数的查询不会改变。
但是,后续版本将有更多图标 ID 和更多 familyStyles。
针对较小版本运行的查询可能会符合复杂度允许范围;但针对较大版本运行的相同查询可能会太大。
但是,也可以使用 version="6.x"
,并且这会随每个版本而改变。
如上所述,虽然 Font Awesome 6.4.2 有 3,690 个图标 ID,但未来的版本将更多。
当您在查询中使用 version="6.x"
时,您要求执行查询时最新的主要版本 6。虽然上面的示例查询在 icons
字段上具有 3,690 的乘数,但如果 Font Awesome 的后续版本有 4,000 个图标 ID,那么相同查询中的相同字段将具有 4,000 的乘数。