2

Just working with the TinkerGraph, and attempting to recursively find nodes connected by a specific edge label (in this case created).

  1. Is there a way I can recursively(/loop) traverse nodes? In the example below, I want to loop until there are no more matching edges (instead of the hardcoded 3 value).
  2. Is there anyway to find and group connected Vertices, given a graph?

Extra kudos for deduplicating nodes, and handling node loops.

Dependencies

compile("com.thinkaurelius.titan:titan-berkeleyje:0.5.4")
compile('com.tinkerpop:gremlin-groovy:2.6.0')

Code (manually recurse 3 times :( )

Gremlin.load()
def g = TinkerGraphFactory.createTinkerGraph()
println g.v(5).as('x')
    .both('created')
    .dedup
    .loop(2){it.loops <= 3}
    .path
    .toList().flatten() as Set // groovy code to flatten & dedup

Gives me: (correct)

[v[5], v[4], v[3], v[1], v[6]]

Thanks!

Nick Grealy
  • 24,216
  • 9
  • 104
  • 119
  • Does this mean you don't want to walk over a vertex you've already visted in the traversal? – Pomme.Verte Apr 01 '15 at 14:30
  • @D.Mill , I don't mind which method is used to get a group of connected nodes. It sounds logical though (depending on your approach) that you wouldn't want to traverse the same vertex twice (to avoid infinite loops), right? – Nick Grealy Apr 01 '15 at 22:21

2 Answers2

3

You don't need any Groovy code, it can be done by only using Gremlin:

gremlin> g.v(5).as('x').both('created').dedup()
gremlin>     .loop('x') {true} {true}.dedup()
==>v[4]
==>v[3]
==>v[5]
==>v[6]
==>v[1]
Daniel Kuppitz
  • 10,846
  • 1
  • 25
  • 34
  • Brilliant, just what I was looking for! Can you explain why the `loop('x') {true} {true}` doesn't just loop indefinitely? I've read the docs, but don't understand how your loop works... http://gremlindocs.com/#branch/loop – Nick Grealy Apr 02 '15 at 00:34
  • It can't loop without if there's no path left (under the hood a FastNoSuchElementException is thrown). The `.dedup()` in `.both('created').dedup()` ensures the no path is traversed twice. – Daniel Kuppitz Apr 02 '15 at 00:42
  • That's really cool. I threw in a loop back `g.v(6).addEdge('created', g.v(4))`, and it didn't even blink. Nice solution. – Nick Grealy Apr 02 '15 at 00:47
0

Here's my current solution. It's a work in progress, so I'm more than happy for improvements and suggestions. (Surely it could be optimised using Gremlin syntax?)

Assumptions: we're given a start node

Gremlin.load()
def g = TinkerGraphFactory.createTinkerGraph()
def startV = g.v(5)
def seen = [startV] // a list of 'seen' vertices
startV.as('x')
    .both('created')
    .filter { // only traverse 'unseen' vertices
        def unseen = !seen.contains(it)
        if (unseen){
            seen << it
        }
        unseen
    }
    .loop('x'){
        // continue looping while there are still more 'created' edges...
        it.object.both('created').hasNext() // ##
    }
    .toList() // otherwise won't process above pipeline
println seen

## I'm not sure why this condition works/doesn't find previously traversed edges. Can anyone explain?

Gives me:

[v[4], v[5], v[3], v[1], v[6]]
Nick Grealy
  • 24,216
  • 9
  • 104
  • 119