本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
在要部署 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) 在本地构建遍历对象。驱动程序将遍历步骤序列化为字节码并将其发送到服务器。在客户端.next()执行诸如.toList()或之类的终端步骤,以迭代服务器返回的结果。您可以将字节码模式与 Java 、 Python 、 Go JavaScript 、 .NET 和其他适用于所用海王星引擎版本的第三方 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 代码,以避免意外交易行为。