Docs
搜索⌘ K
  • 主页
  • 关于 The Graph
  • 支持的网络
  • 协议合约
  • 子图
    • 子流
      • 代币 API
        • 索引
          • 资源
            子图 > 查询

            14 分钟

            GraphQL API

            了解在The Graph中使用的 GraphQL 查询 API。

            什么是GraphQL?

            GraphQL⁠是API的查询语言,也是用您现有数据执行这些查询的运行时间。The Graph使用GraphQL查询子图。

            要理解GraphQL所起的更大作用,请查看 developing 和 创建一个子图。

            用GraphQL查询

            在你的子图模式中,定义了叫做Entities的类型。对于每个Entity类型,entity 和 entities字段将生成在顶级Query类型上。

            注意:在使用The Graph时,query 不需要包含在graphql查询的顶部。

            例子

            查询在您的模式中定义的单个Token实体:

            1{2  token(id: "1") {3    id4    owner5  }6}

            注意:当查询单个实体时,需要填写id字段,它必须是一个字符串。

            查询所有 Token 实体:

            1{2  tokens {3    id4    owner5  }6}

            排序

            查询集合时,您可以:

            • 使用 orderBy 参数按特定属性排序。
            • 使用 orderDirection 来指定排序方向, asc 用于升序或 desc 用于降序。

            示例

            1{2  tokens(orderBy: price, orderDirection: asc) {3    id4    owner5  }6}

            嵌套实体筛选示例

            从Graph节点v0.30.0⁠ 可以根据嵌套实体排序。

            在以下示例中,我们根据代币所有者的名称对其进行排序:

            1{2  tokens(orderBy: owner__name, orderDirection: asc) {3    id4    owner {5      name6    }7  }8}

            目前,您可以在 @entity 和 @orotovedFrom 字段按一级深度String 或 ID类型排序。 不幸的是,按一个深度实体的接口排序⁠,仍不支持按数组和嵌套实体的字段排序。

            分页

            当查询集合时,最好:

            • 从集合开始使用first参数分页。
              • 默认排序顺序是 ID,按字母和数字顺序排列,不是创建时间。
            • 使用 skip 参数跳过实体和分页。例如,first:100 会显示前100个实体,first:100, skip:100会显示后100个实体。
            • 避免在查询中使用 skip 值,因为它们通常表现很差。 要检索大量条目,最好是通过上面示例中显示的属性的实体进行查找。

            使用 first 示例

            查询前10 个代币:

            1{2  tokens(first: 10) {3    id4    owner5  }6}

            查询集合中间的实体群组, skip参数可以与 first参数一起使用,以跳过从集合开始的指定数量的实体。

            使用 first 和 skip 的示例

            查询 10 Token 实体,由集合开始时的10个地方抵消:

            1{2  tokens(first: 10, skip: 10) {3    id4    owner5  }6}

            使用 first 和 id_ge 的示例

            如果客户端需要检索大量实体,则基于属性进行查询和过滤会明显提高性能。 例如,客户端可以使用以下查询检索大量代币:

            1query manyTokens($lastID: String) {    tokens(first: 1000, where: { id_gt: $lastID }) {2      id3      owner4    }5  }6}

            第一次,它会用’lastID = ""发送查询, 对于随后的请求,它会在上次请求中将 lastID设置为最后一个实体的id属性。 这个方法将大大优于使用增加skip`值。

            过滤

            • 您可以在查询中使用 where 参数来过滤不同的属性。
            • 您可以在 where 参数中筛选多个值。

            使用 where 的示例

            使用 ‘失败的’ 结果查询挑战:

            1{2  challenges(where: { outcome: "failed" }) {3    challenger4    outcome5    application {6      id7    }8  }9}

            你可以使用后缀,例如_gt, _lte来进行值比较:

            范围过滤示例

            1{2  applications(where: { deposit_gt: "10000000000" }) {3    id4    whitelisted5    deposit6  }7}

            区块过滤示例

            您也可以筛选在指定的区块中或之后更新的实体使用 _change_block(number_gte: Int)。

            如果您只想获取已经更改的实体,例如自上次轮询以来改变的实体,那么这将非常有用。或者也可以调查或调试子图中实体的变化情况(如果与区块过滤器结合使用,则只能隔离在特定区块中发生变化的实体)。

            1{2  applications(where: { _change_block: { number_gte: 100 } }) {3    id4    whitelisted5    deposit6  }7}

            嵌套实体筛选示例

            在后缀是`_‘的字段中可以根据嵌套的实体进行过滤。

            如果您希望只获取其子级实体满足条件的实体,那么这可能很有用。

            1{2  challenges(where: { application_: { id: 1 } }) {3    challenger4    outcome5    application {6      id7    }8  }9}

            逻辑运算符

            对于Graph节点v0.30.0⁠,您可以在同一个where参数中使用and或or运算符,根据多个标准过滤结果。

            AND运算符

            下面的示例对大于或等于100的outcome、successed和number的挑战进行过滤。

            1{2  challenges(where: { and: [{ number_gte: 100 }, { outcome: "succeeded" }] }) {3    challenger4    outcome5    application {6      id7    }8  }9}

            Synteracc sugar: 你可以通过传递一个用逗号分隔的子表达式来移除and运算符来简化上述查询。

            1{2  challenges(where: { number_gte: 100, outcome: "succeeded" }) {3    challenger4    outcome5    application {6      id7    }8  }9}
            OR运算符

            下面的示例对大于或等于100的outcome、successed和number的挑战进行过滤。

            1{2  challenges(where: { or: [{ number_gte: 100 }, { outcome: "succeeded" }] }) {3    challenger4    outcome5    application {6      id7    }8  }9}

            注意:在构建查询时,重要的是要考虑使用or运算符的性能影响。 虽然or可以成为扩大搜索结果的一个有用工具,但它也可能有很高的费用。 or的主要问题之一是它可能导致查询减缓。 这是因为or需要数据库通过多个索引进行扫描,这可能是一个耗时的过程。 为了避免这些问题,建议开发人员使用和操作人员,而不是在任何可能的情况下使用。 这样可以进行更精确的过滤,可以更快、更准确的查询。

            所有过滤器

            参数后缀的完整列表:

            1_2_not3_gt4_lt5_gte6_lte7_in8_not_in9_contains10_contains_nocase11_not_contains12_not_contains_nocase13_starts_with14_starts_with_nocase15_ends_with16_ends_with_nocase17_not_starts_with18_not_starts_with_nocase19_not_ends_with20_not_ends_with_nocase

            请注意,某些后缀只支持特定类型。 例如,Boolean 只支持 _not、_in和_not_in,但_ 只适用于对象和接口类型。

            此外,下列全局过滤器可以作为where参数的一部分:

            1_change_block(number_gte: Int)

            跨时间查询

            您可以查询您的实体状态,不仅仅是为了最新的区块, 它是默认的,但也是过去的任意区块的。 可以在查询的顶级字段中包含一个 ’ block’ 参数来指定查询的要么用其区块编号或区块哈希。

            这种查询结果不会随着时间的推移而改变,即对过去某个区块的查询,无论何时执行,都将返回相同的结果。唯一的例外是,如果您在非常靠近链头的区块上进行查询,如果该区块不在主链上,并且链被重新组织,则结果可能会改变。 一旦一个区块被确认是最终的区块,那么查询的结果就不会改变。

            请注意,当前的实现仍然受到某些限制,这些限制可能会违反这些保证。该实现不能总是判断给定的区块哈希根本不在主链上,或者对于一个不能被认为是最终的区块,逐块哈希查询的结果可能会受到与查询同时运行的区块重组的影响。当区块是最终区块并且已知在主链上时,它们不会影响区块哈希查询的结果。这个⁠问题详细解释了这些限制是什么。

            示例

            1{2  challenges(block: { number: 8000000 }) {3    challenger4    outcome5    application {6      id7    }8  }9}

            此查询将返回 Challenge 实体及其关联的 Application 实体,因为它们在处理8,000,000个区块后就存在了。

            示例

            1{2  challenges(block: { hash: "0x5a0b54d5dc17e0aadc383d2db43b0a0d3e029c4c" }) {3    challenger4    outcome5    application {6      id7    }8  }9}

            此查询将返回 Challenge 实体及其关联的 Application 实体,因为它们在处理具有给定哈希值的区块后就存在了。

            全文搜索查询

            全文搜索查询字段提供了一个表达性的文本搜索 API,可以添加到子图模式中并进行自定义。 请参阅定义全文搜索字段以将全文搜索添加到您的子图中。

            全文搜索查询有一个必填字段 text,用于提供搜索词。 在这个 text 搜索字段中可以使用几个特殊的全文运算符。

            全文搜索运算符:

            符号运算符描述
            &And用于将多个搜索词组合到包含所有提供词条的实体的过滤器中
            |Or由 or 运算符分隔的多个搜索词的查询,将返回与任何提供的词匹配的所有实体
            <->Follow by指定两个单词之间的距离。
            :*Prefix使用前缀搜索词查找前缀匹配的单词(需要 2 个字符)

            例子

            使用 or 运算符,这个查询将过滤到在其全文字段中具有”anarchism” or “crumpet”变化的博客实体。

            1{2  blogSearch(text: "anarchism | crumpets") {3    id4    title5    body6    author7  }8}

            follow by 运算符指定全文文档中相隔特定距离的单词。 以下查询将返回所有“decentralize”后跟着“philosophy”变体的日志。

            1{2  blogSearch(text: "decentralized <-> philosophy") {3    id4    title5    body6    author7  }8}

            可以将全文运算符进行组合来制作更复杂的过滤器。 在下面的查询示例中,使用前缀搜索运算符与其他运算符的结合,可以实现匹配所有以“lou”开头后,跟着“music”单词的日志实体。

            1{2  blogSearch(text: "lou:* <-> music") {3    id4    title5    body6    author7  }8}

            验证

            Graph节点实现使用 graphql-tools-rs⁠验证它收到的 GraphQL 查询的 specification-based⁠ 验证基于 graphql-js 参考实现⁠。 查询失败的验证规则有一个标准错误 - 请访问 GraphQL spec⁠来了解更多信息。

            模式

            您的数据源模式,例如可用于查询的实体类型、值和关系是通过 GraphQL 接口定义语言(IDL)⁠定义的。

            GraphQL模式通常定义查询、订阅和突变的根类型。The Graph仅支持查询。子图的根查询类型是从子图清单中包含的GraphQL模式自动生成的。

            注意:我们的 API 不提供对突变的支持,因为开发人员会从他们的应用程序中直接针对底层区块链发出交易。

            实体

            模式定义中所有带有 @entity 指示的 GraphQL 类型都将被视为实体,并且必须具有 ID 字段。

            注意: 目前,您的模式中的所有类型都必须有一个 @entity 指令。 今后,我们将把没有@entity指令的类型视为值对象,但这还不被支持。

            子图元数据

            所有子图都有一个自动生成的_Meta_对象,它提供对子图元数据的访问。可按如下方式查询:

            1{2  _meta(block: { number: 123987 }) {3    block {4      number5      hash6      timestamp7    }8    deployment9    hasIndexingErrors10  }11}

            如果提供了区块,则元数据为该区块的元数据,如果未使用最新的索引区块。如果提供,则区块必须在子图的起始区块之后,并且小于或等于最近索引的区块。

            deplement 是一个唯一的ID,与 subgraph.yaml 文件的 IPFS CID 相对应。

            block 提供了关于最新区块的信息(同时考虑到传递给_meta的任何区块约束):

            • hash:区块的哈希
            • number:区块编号
            • timestamp:区块的时间戳,如果可用的话(当前仅适用于索引EVM网络的子图)

            hasIndexingErrors是一个布尔值,用于标识子图在过去的某个区块中是否遇到索引错误。

            ⁠在GitHub上编辑⁠

            分布式系统子图 ID vs 部署 ID
            在此页面上
            • 什么是GraphQL?
            • 用GraphQL查询
            • 例子
            • 排序
            • 分页
            • 过滤
            • 跨时间查询
            • 全文搜索查询
            • 验证
            • 模式
            • 实体
            • 子图元数据
            The GraphStatusTestnetBrand AssetsForum安全Privacy PolicyTerms of Service