本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
在要部署 Gremlin 代码的上下文中对其进行测试
Gremlin 为客户端提供了多种向服务器提交查询的方法。这些提交模式的不同之处在于查询的评估方式和交易的行为方式。如果您在一种模式下开发而在另一种模式下部署,则这些差异可能会导致意想不到的结果。
脚本模式(基于字符串的提交)
在脚本模式下,客户端将整个查询作为文本字符串发送到服务器。服务器评估完整的字符串,包括所有终端步骤,并将结果流回客户端。以下工具和方法使用脚本模式:
Gremlin 控制台 — 使用命令时
:remote通过 TinkerPop 驱动程序提交查询字符串(例如,
client.submit("g.V().count()")在 Java 中使用)
在脚本模式下,客户端将如下所示的查询作为完整字符串发送到服务器:
// Script mode – the entire string, including .next(), is sent to the server // V('non-existing-id') yields nothing because no vertex with that ID exists Cluster cluster = Cluster.build().addContactPoint("your-neptune-endpoint") .port(8182).enableSsl(true).create(); Client client = cluster.connect(); client.submit("g.V('existing-id').addV('person').V('non-existing-id').next()");
服务器评估完整的查询,包括.next()。如果未.next()找到任何结果,则服务器会引发NoSuchElementException,事务将回滚。
字节码模式(GLV 遍历对象)
在字节码模式下,客户端使用 Gremlin 语言变体 (GLV) 在本地构建遍历对象。驱动程序将遍历步骤序列化为字节码并将其发送到服务器。终端步骤(例如.toList()或)在客户端.next()执行,以迭代服务器返回的结果。你可以将字节码模式与 Java、Pyth on、Go JavaScript、.NET 和其他适用于所用的 Neptune 引擎版本的第三方 TinkerPop-compliant 驱动程序一起使用。
在字节码模式下,相同的查询如下所示:
// Bytecode mode – the driver sends the traversal steps as bytecode // .next() executes on the client to iterate results Cluster cluster = Cluster.build().addContactPoint("your-neptune-endpoint") .port(8182).enableSsl(true).create(); GraphTraversalSource g = traversal().withRemote( DriverRemoteConnection.using(cluster)); g.V("existing-id").addV("person").V("non-existing-id").next();
驱动程序仅将遍历步骤 (g.V().addV().V()) 作为字节码发送。服务器成功评估遍历,提交事务并返回结果集。然后,客户端.next()在本地调用以读取结果集。如果结果集为空,则客户端会引发NoSuchElementException,但事务已在服务器上提交。
交易行为差异
这些模式之间的关键区别在于终端步骤如何影响交易:
脚本模式-服务器评估终端步骤。如果像这样的终端步骤因为结果集为空而
.next()失败,则服务器会将查询视为失败并回滚事务。服务器不会在同一次遍历中保留任何突变(例如)。addV()字节码模式 — 客户端评估终端步骤。服务器仅评估遍历步骤,成功提交事务并返回结果。如果客户端随后调用
.next()空结果集,则结果仅NoSuchElementException是客户端错误。事务已经提交,因此服务器会保留任何变更。
终端步骤
在 Gremlin 中,终端步骤
hasNext()—true如果有结果则返回,false否则返回。next()— 返回下一个结果。NoSuchElementException如果不存在任何结果,则抛出。next(n)— 以列表形式返回下一个n结果。toList()— 以列表形式返回所有结果。如果不存在任何结果,则返回一个空列表。toSet()— 将所有结果作为一个集合返回。如果不存在任何结果,则返回一个空集。iterate()— 迭代所有结果而不返回它们。将其用于不需要返回值的突变。
注意
各个语言 GLV 可能会提供特定于其实现的其他终端步骤。有关详细信息,请参阅特定语言的页面。
如果您在一个上下文中开发和测试代码,则可能会遇到问题。例如,Gremlin 控制台以脚本形式提交查询。如果您将代码部署在不同的上下文中,例如通过使用字节码的 Java 驱动程序进行部署,则代码在生产环境中的行为可能会有所不同。
重要
请务必使用与部署 Gremlin 代码相同的提交模式来测试 Gremlin 代码,以避免意外的事务行为。