GremlinPipeline while loop help

208 views
Skip to first unread message

Jonas Michel

unread,
Feb 25, 2015, 6:17:26 PM2/25/15
to gremli...@googlegroups.com
Hello,

I'm building a GremlinPipeline (v 2.5.0) and I think I've run into good use case for a loop, but I'm struggling with the plumbing (pun intended). Any suggestions are appreciated.

Here's my graph of framed vertices...

                               Message
                                     |
                           [transmission]
                                     |
                                    v
    /----[knows]---> Transmission <---[knows]---\
    |                                ^                                  |
    |                                |                                   |
    |                            [event]                             |
    |                                |                                   |
Host ---[contact]---> Contact <---[contact]--- Host


...where Know edges have a long "time" property and Hosts vertices have a String "id" property.

What I'd like is to obtain all of the Transmissions "known" by a particular Host up to a certain time along a traversal "up" a tree (back in time).  

Here's an example. Given the following binary-tree-like graph of Hosts with one (not shown) Contact having one (not shown) Transmission per Host-Host edge...

                                  Host4
                                /
                 Host2 ---
               /                \ 
              /                   Host5
Host1 ---
               \                 Host6
                \               / 
                 Host3 ---
                                \
                                  Host7

...beginning at Host7, my desired output would be [Transmission(3, 7), Transmission(3, 6), Transmission(1, 3), Transmission(1, 2)], where Transmission(X, Y) means the Transmission that occurred on the Contact between HostX and HostY. Basically I would like the path from Host7 to the root (Host1) and the neighbors at each level along the way.

So given a host and a time and beginning from a message (this), my attempt at this so far looks like...

new GremlinPipeline(this)
  .out("transmission") // all message transmissions
  .as("x")
  .inE("knows")
  .has("time", Compare.LESS_THAN_EQUAL, time) // known time <= time
  .outV() // hosts "knowing" the transmissions
  .retain(Arrays.asList(host)) // just the desired host
  .back("x") // now we have all transmissions of this message known by the host <= time
  .as("y")
  .loop("y"
    // this is where I'm stuck...
    // I'd like to loop backwards in time along transmissions on contacts between hosts on the path to the root
    // and emit the transmission at its neighbors at each level
  ).gather()

Am I on the right track...?

Thanks!

Jonas Michel

unread,
Feb 26, 2015, 12:49:44 PM2/26/15
to gremli...@googlegroups.com
I think I've come up with part of a solution, but it requires referencing variables that exist outside the scope of the inner-class PipeFunction closures, which isn't allowed. I'm still getting the hang of Gremlin and would really appreciate any feedback or suggestions.

So I guess two questions: is there a better way to perform this traversal and how do I access and modify variables within a loop/side-effect?

Here's my partial approach, which only returns the Transmissions on the path back to the root Host, not the neighbors along the way...

Host currentHost = host
long currentTime = Long.MAX_VALUE;

new GremlinPipeline(this)
  .out("transmission") // all message transmissions
  .as("x")
  .inE("knows")
  .has("time", Compare.LESS_THAN_EQUAL, time) // known time <= time
  .outV() // hosts "knowing" the transmissions
  .retain(Arrays.asList(host)) // just the desired host
  .back("x") // now we have all transmissions of this message known by the host <= time
  .as("y")
  .in("event")
  .in("contact")
  .retain(Arrays.asList(currentHost))
  .back("y") // now we have the transmission that brought this message to the current host reference
  .loop("y"
    new PipeFunction<LoopBundle<Vertex>, Boolean>() {
      public Boolean compute(LoopBundle<Vertex> it) {
        return ((long) it.getObject().getProperty("time")) < currentTime; // loop until we can't go any further back in time
      }
    },
    new PipeFunction<LoopBundle<Vertex>, Boolean>() {
      public Boolean compute(LoopBundle<Vertex> it) {
        return true; // always emit the Transmission vertex
      }
    }
  )
  .sideEffect(
    new PipeFunction<Vertex, Vertex>() {
        public Vertex compute(Vertex it) {
          // update the host and time references
          currentHost = (Host) new GremlinPipeline(it).in("event").in("contact").hasNot("host-id", currentHost.getId()).next();
          currentTime = (long) it.getProperty("time");
        }
      }
  )

Jonas Michel

unread,
Feb 27, 2015, 1:32:27 AM2/27/15
to gremli...@googlegroups.com
I ended up solving this by "cheating"...I changed my graph schema. After adding "sent" and "received" edges from Hosts to Transmissions I can traverse the Transmissions more directly. The query simplifies to the traversal in this post.


On Wednesday, February 25, 2015 at 5:17:26 PM UTC-6, Jonas Michel wrote:

Daniel Kuppitz

unread,
Feb 27, 2015, 11:45:14 AM2/27/15
to gremli...@googlegroups.com
Hey Jonas,

can you provide a Gremlin script that creates a sample graph? It would make it much easier to help you out.

but it requires referencing variables that exist outside the scope of the inner-class PipeFunction closures, which isn't allowed

Did you consider to use Groovy? It will wrap you code accordingly under the hood, so that you don't run into this limitation. You can do it in Java as well, it just requires a lot more code.

Cheers,
Daniel


--
You received this message because you are subscribed to the Google Groups "Gremlin-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gremlin-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/gremlin-users/bca5bb2d-9386-4c9e-b98d-3bd81e07efa2%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages