跳至内容
欢迎 Web Awesome,这是最大的、最好的开源 Web 组件库。
立即预购!

查询复杂度

管理查询的复杂度以提高性能并防止错误响应。

何时查询太复杂?

我们有很多版本,每个版本都有数千个图标,而且大多数图标都可以在几种 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 中的所有图标。对于每个图标,它获取 idunicode 字段,以及三种 familySyles 的 svgs:Classic Solid、Classic Light 和 Classic Regular。对于每个 SVG,它选择四个字段。

让我们看看为什么它过于复杂。

计算查询复杂度的基本经验法则是在考虑某些字段(如 iconssvgs 表示多个)的情况下,为每个选定的字段计数 1

自下而上

正在为 svgs 选择三种 familyStyles,因此该字段的乘数为 3。并且在 svgs 下选择了 4 个字段。这意味着 svgs 字段的复杂度将为每个图标的 3 * 4 == 12

每个图标还具有 idunicode。因此,每个图标的复杂度为 14svgs12,加上其他 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 对象上的各种字段。例如,它的 unicodelabel

因此,对应于 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 的乘数。