2
votes

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!

2
Does this mean you don't want to walk over a vertex you've already visted in the traversal? - Pomme.Verte
@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

2 Answers

3
votes

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]
0
votes

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]]