在 Neptune 中如何处理 Gremlin 查询 - Amazon Neptune
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

在 Neptune 中如何处理 Gremlin 查询

在 Amazon Neptune 中,可以通过一系列模式来表示更复杂的遍历。模式基于命名变量的定义创建关系,该变量可以在模式之间共享以创建联接。如下例所示。

问题:顶点有哪些两跳邻域?v1?

Gremlin code: g.V(‘v1’).out('knows').out('knows').path() Pattern: (?1=<v1>, <knows>, ?2, ?) X Pattern(?2, <knows>, ?3, ?) The pattern produces a three-column relation (?1, ?2, ?3) like this: ?1 ?2 ?3 ================ v1 v2 v3 v1 v2 v4 v1 v5 v6

通过在两个模式之间共享 ?2 变量(在第一个模式的 O 位置和第二个模式的 S 位置),可以创建从一跳邻域到二跳邻域的联接。每个 Neptune 解决方案都具有三个命名变量的绑定,可用于重新创建TinkerPop Traverser(包括路径信息)。

Gremlin 查询处理的第一步是将查询解析为 TinkerPop 遍历对象,由一系列 TinkerPop 步骤. 这些步骤是开源的一部分阿帕奇 TinkerPop 项目,是构成参考实现中 Gramlin 遍历的逻辑和物理运算符。它们都用于表示查询模型。它们是可执行的运算符,可以根据其代表的运算符的语义生成解决方案。例如,.V()由表示和执行 TinkerPop GraphStep.

由于这些 off-the-shelf TinkerPop 步骤是可执行的,例如 TinkerPop 遍历可以执行任何 Gemlin 查询并生成正确的答案。但是,当针对大型图执行时, TinkerPop 步骤有时会非常低效且缓慢。如前所述,Neptune 试图将遍历转换为由模式组组成的声明形式,而不是使用它们。

目前,Neptune 在本机查询引擎中支持所有 Gemlin 运算符(步骤)。因此,它尝试将尽可能多的步骤折叠为一个 NeptuneGraphQueryStep,其中包含已转换的所有步骤的声明性逻辑查询计划。理想情况下,所有步骤都将转换。但是,当遇到无法转换的步骤时,Neptune 会中断本机执行,并将所有查询执行从该点推迟到 TinkerPop 步骤。它不会尝试穿插进行本机执行。

在将步骤转换成逻辑查询计划后,Neptune 将运行一系列查询优化器,根据静态分析和估计基数来重写查询计划。优化器执行多种操作,例如根据范围计数对运算符进行重新排序、删除不必要或多余的运算符、重新排列筛选条件、将运算符推入不同的组等。

生成优化的查询计划后,Neptune 创建物理运算符管道来执行查询。这包括从语句索引中读取数据、执行各种类型的联接、筛选、排序等。管道生成解决方案流,然后将其转换回 TinkerPop Traverser 对象流。

查询结果的序列化

Amazon Neptune 目前依赖 TinkerPop 将查询结果 (TinkerPop Trverers) 转换为序列化数据,以通过线路发送回客户端。这些序列化格式往往很冗长。

例如,序列化等顶点查询的结果,例如g.V().limit(1)之后,Neptune 查询引擎必须执行一次搜索来生成查询结果。但是,GraphSON 序列化程序将执行大量额外的搜索,才能将顶点打包为序列化格式。它必须执行一次搜索来获取标签,执行一次搜索来获取属性键,并对顶点的每个属性键执行一次搜索来获取每个键的所有值。

某些序列化格式效率更高,但是所有序列化格式都需要进行额外的搜索。此外, TinkerPop 序列化程序不会尝试避免重复搜索,这往往会导致很多不必要的重复搜索。

因此,在编写查询时,只询问所需的信息极为重要。例如,g.V().limit(1).id() 将仅返回顶点 ID,并消除所有其他序列化程序搜索。GremlinprofileNeptune 中的 API 允许您查看在查询执行和序列化期间进行了多少次搜索调用。