我有一个用例,我必须从一个特定的顶点开始遍历一串顶点 . 它是一个线性链(像火车),只有一个顶点连接到前一个 . 虽然遍历我必须根据一些标准发射某些顶点,直到我到达链的末端 .
第二个用例是上述用例的扩展,但不是从单个顶点开始的单个链,而是有多个这样的链,同样从单个顶点开始 . 我必须遍历每个链并检查顶点中的特定属性值 . 当找到该属性匹配时,我必须发出该顶点,并以第二个链开始,依此类推 .
我必须使用Gremlin java API实现这一点 . 这看起来很简单,但我是gremlin的新手,并且在gremlin java API上没有太多关于互联网的帮助 .
1 回答
将Gremlin Groovy转换为Gremlin Java应该不是很困难 . 我总是反对这样做:
大大增加代码的大小
使您的代码可读性降低
使您的代码更难维护
如果你在一个不会听到外部编程语言的“Java商店”工作,我认为仅仅通过几个例子来说明Gremlin在groovy和java中的差异就很难卖掉那些人(很容易阅读一个内衬与可能是数百行代码的内容 . 此外,Groovy可以在同一模块中与java一起使用,也可以在其他项目所依赖的独立模块中适用于标准Maven项目 . 在大多数情况下,我更喜欢后者,因为您在单个包中隔离了groovy,并且在多个用例中可以重复使用DSL(例如,应用程序,gremlin控制台中的附加库等) .
也就是说,如果你仍然必须使用Java,我仍然可以从编写Groovy开始 . 使用Gremlin控制台并正确获取遍历算法 . 听起来好像你的两个用例都涉及循环,所以我们只是说你的遍历看起来像:
这将从顶点“1”遍历链,直到我耗尽链,在第一个闭包中用“true”表示,然后在第二个闭包中发出符合我标准的任何顶点 . 一旦你有大量的Gremlin定义和测试,就可以转换为Java了 .
如您所知,以
GremlinPipeline
开头,第一部分非常容易进行转换:正如您所看到的,Groovy方法几乎可以非常干净地映射到Java,直到您需要一个闭包并且
loop
是需要一个闭包的步骤之一 . 要使用Gremlin Java,您可能会发现查看javadoc forGremlinPipeline
非常有用 .我使用了
loop
的三个参数版本 - 标记为"deprecated"的那个(但是我们的目的没问题) - 你可以看到here . 第一个参数很简单 - 一个整数,所以翻译的第一部分是:我已经将占位符留给了我们拥有的另外两个封口 . 如果以这种方式看待它,它与我们的Groovy版本没有什么不同 - 语法略有不同 .
在Java 8之前,没有内置于java语言中的闭包概念 . 请注意,在TinkerPop3中,Gremlin已经发生了巨大变化,以利用我们现在拥有lambda的事实 . 但是当你在TinkerPop2中时,你必须使用内置的
PipeFunction
,它基本上代表我们的groovy闭包的类型版本 . 循环的两个参数的PipeFunction
是:所以基本上,这是一个函数,它将
LoopPipe.LoopBundle
作为一个包含循环元数据的对象,并期望返回一个布尔值 . 如果你理解了这个概念,那么所有的Gremlin Java都会为你打开,因为你看到一个groovy闭包的地方,你知道它下面只是java中某种形式的PipeFunction
,并且你现在可以阅读PipeFunction
的期望了 . 从javadocs开始,这些语言翻译应该是直截了当的 .我们必须做的第一个闭包翻译就像它一样直截了当 - 我们只需要
PipeFunction
返回true
:因此,对于
loop
的第二个参数,我们必须构造一个新的PipeFunction
,它有一个名为compute
的方法 . 从那个方法我们返回true
. 现在来处理控制的第二个PipeFunction
参数要发出的顶点:并且存在转换 . 由于这是一个很长的帖子,让我们把原始的groovy放在更接近上面的位置,这样差别很明显:
我们从上面的一行代码转到了近十几行,这是一个非常简单的遍历 . Gremlin Java在TinkerPop3中自成一体,给出了lambdas和语言本身的重大改进,但是这些先前的版本产生的java代码在Groovy可以使事情非常整洁时非常值得生成或维护 .