GremlinPipeLine在Titan图形用例中的java API链遍历 [英] GremlinPipeLine java API chain traversal in Titan graph use cases

查看:156
本文介绍了GremlinPipeLine在Titan图形用例中的java API链遍历的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用例,我必须从一个特定的顶点开始遍历一串顶点。它是一个线性链(像火车),只有一个顶点连接到前一个。虽然遍历我必须根据一些标准发射某些顶点,直到我到达链的末尾。

I have use case where in I have to traverse a chain of vertices starting from a particular vertex. Its a linear chain (like a train) with only one vertex connected to the previous.While traversing I have to emit certain vertices based on some criteria until I reach the end of the chain.

第二个用例是上述用例的扩展,但不是从单个顶点开始的单个链,而是有多个这样的链,同样从单个顶点开始。我必须遍历每个链并检查顶点中的特定属性值。当找到该属性匹配时,我必须发出该顶点,并以第二个链开始,依此类推。

The second use case is the extension of the above use case but instead of a single chain starting from a single vertex, there are multiple such chains , again starting from a single vertex. I have to traverse each chain and check for a particular property value in the vertices. When that property match is found I have to emit that vertex and the start with second chain and so on.

我必须使用Gremlin java API实现这一点。这看起来很简单,但我是gremlin的新手,并且在gremlin java API上没有太多关于互联网的帮助。

I have to achieve that using Gremlin java API. This appears to be a simple one, but I am new to gremlin and there is not much help from the internet either on gremlin java API.

推荐答案

将Gremlin Groovy转换为Gremlin Java应该不是很困难。我总是反对这样做:

Converting Gremlin Groovy to Gremlin Java shouldn't be very difficult. I would always argue against doing it as you will:


  1. 大大增加代码的大小

  2. 使您的代码不易阅读

  3. 让您的代码更难维护

如果您在一个不会听到外部编程语言的Java商店,我认为仅仅通过几个例子来说明Gremlin在groovy和java中的差异(仅易于阅读一个内衬vs)什么可能是几百行代码。此外,Groovy可以在同一模块中与java一起使用,也可以在其他项目所依赖的独立模块中适用于标准Maven项目。在大多数情况下,我更喜欢后者,因为你将groovy隔离在一个软件包中,并且可以在多个用例中作为DSL重用(例如应用程序,gremlin控制台中的附加库等)。

If you work in a "Java shop" that won't hear of an outside programming language, I think that it's not too hard to sell folks on those points with just a few examples of the differences Gremlin has in groovy and java (easy to read one liners vs. what could be hundreds of lines of code). Furthermore, Groovy can fit into a standard Maven project either alongside java in the same module or in a separate standalone module that other projects depend on. In most cases, I prefer the latter as you isolate your groovy in a single package and that becomes reusable as a DSL across multiple use cases (e.g. an application, a add-on lib in the gremlin console, etc.).

也就是说,如果你仍然必须使用Java,我仍然可以从编写Groovy开始。使用Gremlin控制台并获得正确的遍历算法。听起来好像你的两个用例都涉及循环,所以我们只是说你的遍历看起来像:

That said, if you still must use Java, I would still start by writing Groovy. Use the Gremlin Console and get your traversal algorithm right. It sounds as though both of your use cases involve looping, so we'll just say that your traversal looks something like:

g.v(1).out.loop(1){true}{it.object.someProperty=="emitIfThis"}

这样就会从顶点1遍历链,直到我耗尽链,在第一个闭包中用true表示,然后在第二个闭包中发出符合我标准的任何顶点。一旦你有大量的Gremlin定义和测试,就可以转换为Java了。

So that would traverse the chain from vertex "1" until I exhaust the chain, signified by "true" in the first closure, and then emit any vertex that matches my criteria in the second closure. Once you have that much of your Gremlin defined and tested, it's time to convert to Java.

如您所知,以 GremlinPipeline 开头,第一部分很容易转换:

As you know that starts with a GremlinPipeline and the first part is pretty easy for conversion purposes:

new GremlinPipeline(g.getVertex(1)).out()

正如你所看到的,Groovy方法几乎可以非常干净地映射到Java,直到你需要一个闭包和循环是需要一个步骤的步骤之一。要使用Gremlin Java,您可能会发现查看 GremlinPipeline 的html> javadoc

As you can see, the Groovy approach will pretty much map to Java fairly cleanly until you get to a point where you need a closure and loop is one of those steps that requires one. To work with Gremlin Java you will probably find it useful to look at the javadoc for GremlinPipeline.

我使用了 loop 的三个参数版本 - 标记为已弃用的版本(但这对我们的目的来说没问题) ) - 你可以看到它这里。第一个参数很简单 - 一个整数,所以翻译的第一部分是:

I used the three argument version of loop - the one marked "deprecated" (but that's ok for our purposes) - you can see it here. The first argument is simple - an integer so the first part of the translation is:

new GremlinPipeline(g.getVertex(1)).out().loop(1, closure, closure)

我已经离开了持有者我们拥有的另外两个闭包。如果以这种方式看待它,它与我们的Groovy版本没有什么不同 - 语法略有不同。

I've left place holders for the two other closures that we have. If you look at it this way, it's really not that different from our Groovy version - ever so slightly different syntax.

在Java 8之前,java langauge中没有内置闭包的概念。请注意,在 TinkerPop3 中,Gremlin已经发生了巨大变化,以利用我们现在拥有lambda的事实。但是当你在TinkerPop2中时,你必须使用内置的 PipeFunction ,它基本上代表我们的groovy闭包的类型版本。循环参数的 PipeFunction 是:

Prior to Java 8 there was no notion of closures built into the java langauge. Note that in TinkerPop3, Gremlin has changed dramatically to take advantage of the fact that we now have lambdas. But as you are in TinkerPop2, you have to use the built in PipeFunction which essentially represents typed versions of our groovy closures. The PipeFunction for both arguments to loop is:

PipeFunction<LoopPipe.LoopBundle<E>,Boolean>

基本上,这是一个得到 LoopPipe.LoopBundle的函数作为一个对象,它包含有关循环的元数据,并期望返回一个布尔值。如果你理解了这个概念,那么所有的Gremlin Java都会为你打开,因为你看到一个groovy闭包,你知道它下面只是某种形式的 PipeFunction in java并且鉴于您现在可以从javadocs读取 PipeFunction 的期望,应该可以直接进行这些语言翻译。

So basically, this is a function that gets a LoopPipe.LoopBundle as an object which contains metadata about the loop and expects that you return a boolean value. If you understand that concept, then all of Gremlin Java opens up for you, because everywhere that you see a groovy closure, you know that underneath it is just some form of PipeFunction in java and given that you can now read the expectations of a PipeFunction from the javadocs, it should be straightforward to do these language translations.

我们要做的第一个闭包翻译就像它到来一样简单 - 我们只需要我们的 PipeFunction 来返回 true

The first closure translation we have to do is as straightforward as it come - we just need our PipeFunction to return 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 参数:

So, for the second argument to loop we have to construct a new PipeFunction, which has one method called compute. From that method we return true. Now to handle the second PipeFunction argument that controls the vertices to emit:

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放在更接近上面的位置,这样差别很明显:

And there stands the conversion. As this is a long post, let's place the original groovy closer to the above so that the difference are clear:

g.v(1).out.loop(1){true}{it.object.someProperty=="emitIfThis"}

我们从上面的一行代码转到了近十几个,这是一个非常简单的遍历。 Gremlin Java在TinkerPop3中自成一体,给出了lambda和语言本身的重大改进,但是这些先前版本产生的java代码在Groovy可以使事情变得非常整洁时非常值得生成或维护。

We went from the above one line of code to nearly a full dozen on what was an otherwise very simple traversal. Gremlin Java comes into its own in TinkerPop3 given lambdas and a major overhaul of the language itself, but these prior versions produce java code that really isn't worth the effort generating or maintaining when Groovy can make things very neat and tidy.

这篇关于GremlinPipeLine在Titan图形用例中的java API链遍历的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆