我有用例,在其中,我必须遍历从特定顶点开始的一系列顶点。它是一个线性链(如火车),只有一个顶点连接到previous.While遍历,我必须根据某些准则发出某些顶点,直到到达链的末尾。
第二个用例是上述用例的扩展,但不是从单个顶点开始的单链,而是有多个这样的链,同样从单个顶点开始。我必须遍历每条链,并检查顶点中的特定属性值。当找到该属性匹配时,我必须发出这个顶点和以第二链开始,以此类推。
我必须使用来实现这一点。这看起来很简单,但我对gremlin并不熟悉,在gremlin java API上也没有从互联网上得到多少帮助。
发布于 2015-04-02 11:20:34
将Gremlin转换为Gremlin不太困难。我总是反对这样做,因为你愿意:
如果您在一个"Java商店“中工作,它不会听说外部编程语言,我认为在这些点上卖给人们并不难,只举几个Gremlin在groovy和java (易于阅读的一行代码和可能有数百行代码的代码)之间的差异的例子。此外,Groovy可以与java一起安装在同一个模块中,也可以安装在其他项目所依赖的独立模块中。在大多数情况下,我更喜欢后者,因为您将groovy隔离在一个包中,并且可以在多个用例中作为DSL重用(例如,应用程序,gremlin控制台中的附加库,等等)。
尽管如此,如果您仍然必须使用Java,我仍然会从编写Groovy开始。使用Gremlin控制台并使遍历算法正确。听起来好像这两个用例都涉及循环,所以我们只需要说您的遍历看起来类似于:
g.v(1).out.loop(1){true}{it.object.someProperty=="emitIfThis"}因此,这将遍历链从顶点"1“直到我用尽链,在第一个闭包中以"true”表示,然后发出与我在第二个闭包中的标准相匹配的任何顶点。一旦定义并测试了Gremlin的大部分内容,就应该转换为Java了。
如您所知,从GremlinPipeline开始,第一部分很容易实现转换:
new GremlinPipeline(g.getVertex(1)).out()如您所见,Groovy方法将相当清晰地映射到Java,直到您达到需要闭包的地步,而loop就是其中一个需要闭包的步骤。要使用Gremlin,您可能会发现查看javadoc for GremlinPipeline很有用。
我使用了loop的三个参数版本--标记为“反推荐”的版本(但就我们的目的而言,没关系)--您可以看到它here。第一个参数很简单--一个整数,所以翻译的第一部分是:
new GremlinPipeline(g.getVertex(1)).out().loop(1, closure, closure)我已经把位置持有者留给了另外两个封闭的地方。如果您这样看的话,它实际上与Groovy版本并没有太大的不同--语法也略有不同。
在Java 8之前,java语言中没有内置闭包的概念。请注意,在TinkerPop3中,Gremlin发生了巨大的变化,以利用我们现在有lambdas这一事实。但是在TinkerPop2中,您必须使用内置的PipeFunction,它实质上代表了groovy闭包的类型化版本。这两个参数循环的PipeFunction是:
PipeFunction<LoopPipe.LoopBundle<E>,Boolean>因此,基本上,这是一个函数,它将一个LoopPipe.LoopBundle作为一个对象,它包含关于循环的元数据,并期望您返回一个布尔值。如果您理解这个概念,那么所有Gremlin Java都会为您打开,因为在您看到groovy闭包的任何地方,您都知道它下面只是java中的某种形式的PipeFunction,并且考虑到您现在可以从javadocs中读取PipeFunction的期望,那么进行这些语言转换应该很简单。
我们必须做的第一个闭包转换非常简单--我们只需要我们的PipeFunction返回true。
new GremlinPipeline(g.getVertex(1)).out().loop(1,
new PipeFunction<LoopPipe.LoopBundle<Vertex>,Boolean>() {
public Boolean compute(LoopPipe.LoopBundle<Vertex> argument) {
return true;
}
}, closure)因此,对于loop的第二个参数,我们必须构造一个新的PipeFunction,其中有一个名为compute的方法。通过该方法,我们返回true。现在,要处理控制要发出的顶点的第二个PipeFunction参数:
new GremlinPipeline(g.getVertex(1)).out().loop(1,
new PipeFunction<LoopPipe.LoopBundle<Vertex>,Boolean>() {
public Boolean compute(LoopPipe.LoopBundle<Vertex> argument) {
return true;
}
},
new PipeFunction<LoopPipe.LoopBundle<Vertex>,Boolean>() {
public Boolean compute(LoopPipe.LoopBundle<Vertex> argument) {
return argument.getObject().getProperty("someProperty").equals("emitIfThis");
}
})那里站着皈依。由于这是一个很长的帖子,让我们将原来的groovy更接近于上面的内容,这样区别就很明显了:
g.v(1).out.loop(1){true}{it.object.someProperty=="emitIfThis"}我们从上面的一行代码转到了一个非常简单的遍历过程中的几乎全部代码。鉴于lambdas和语言本身的重大变革,Gremlin在TinkerPop3中有了自己的版本,但这些早期版本产生的Java代码实际上不值得在Groovy能够使事情变得非常整洁的情况下进行生成或维护。
https://stackoverflow.com/questions/29409219
复制相似问题