Extract edges / nodes from a path

1,762 views
Skip to first unread message

Amergin

unread,
Oct 10, 2012, 5:07:53 AM10/10/12
to gremli...@googlegroups.com
Is there a method for extracting all edges within a path? Consider this trivial example:

gremlin> g.v(123).out[0].out[0].paths
==> [v[123], v[2192], v[39324]]

Would it possible to get the edges of this path without having to use a sideEffect or a similar way to manually record the edge on each step?


Stephen Mallette

unread,
Oct 10, 2012, 5:44:12 AM10/10/12
to gremli...@googlegroups.com
does this help:

gremlin> g = TinkerGraphFactory.createTinkerGraph()
==>tinkergraph[vertices:6 edges:6]
gremlin> g.v(1).outE.inV.outE.inV.path
==>[v[1], e[8][1-knows->4], v[4], e[10][4-created->5], v[5]]
==>[v[1], e[8][1-knows->4], v[4], e[11][4-created->3], v[3]]

stephen
> --
>
>

Amergin

unread,
Oct 10, 2012, 7:50:30 AM10/10/12
to gremli...@googlegroups.com
Not really, I was hoping for a way in which I can create any type of long query, and at the end of it call a method like .path that only lists the edges. As I understand it, the traversal is a pipeline from start to end so, at least conceptually, this should be possible.

Specifically I'm trying to build a query like the below cypher query:

    querystr = "START clin=node(%s) MATCH path = clin-[rel1]->middle-[rel2]->target WHERE (middle.source! = '%s') AND " %(startNode._id, middleNodeType)
    querystr += "("
    querystr += "( (middle.label! = target.label!) AND (middle.chr! = target.chr!) AND (target.source! = '%s') ) OR " % (targetNodeType)
    querystr += "( (middle.chr! = target.chr!) AND (target.source! = 'CNVR') AND ( rel2.distance! < %i ) AND ( rel2.correlation! > 0 ) ) OR " %(distanceThreshold)
    querystr += "( (middle.chr! = target.chr!) AND (target.source! = 'METH') AND ( rel2.distance! < %i ) AND ( rel2.correlation! < 0 ) ) OR " %(distanceThreshold)
    querystr += "( (target.source! = 'MIRN') AND ( rel2.correlation! < 0 ) )"
    querystr += ")"
    querystr += "RETURN EXTRACT( r in relationships(path) : ID(r) ) ORDER BY rel2.%s %s LIMIT %i" %(targetEdgeOrderAttr1, targetEdgeOrdering1, noNodes)

Which I believe would be something like

            middle = null;
            rel2 = null;
            resultEdgeIds = [];
            g.v(clinicalNodeId).out.filter{ it.getProperty('source') == 'GEXP' }.as('middle').sideEffect{ middle = it }.outE.sideEffect{rel2 = it}.inV.filter
            {
                return
                (
                    ( ( it.hasProperty('label') && middle.hasProperty('label') && it.getProperty('label') == middle.getProperty('label') )  &&
                        ( it.chr == middle.chr ) && ( middle.source == targetType ) ) ||
                    ( ( it.chr == middle.chr ) && ( it.source == 'CNVR' )
                        && ( rel2.getProperty('distance') < distanceThreshold ) && ( rel2.getProperty('correlation') > 0 ) ) ||
                    ( ( it.chr == middle.chr ) && ( it.source == 'METH' ) &&
                        ( rel2.getProperty('distance') < distanceThreshold ) && ( rel2.getProperty('correlation') < 0 ) ) ||
                    ( (it.source == 'MIRN') && (rel2.correlation < 0) )
                );
            }.paths -> something

Introducing .outE.inV like structure would require the modification of how filtering is done. I was hoping Gremlin would have a Cypher-like feature of naming the whole traversal path (path = .. above) and later I would be able to extract edges from that ( EXTRACT( r in relationships(path) ).

Marko Rodriguez

unread,
Oct 10, 2012, 9:50:21 AM10/10/12
to gremli...@googlegroups.com
Hi,

The path() step simply emits what has been touched in the traversal. Hence, if you jump from vertex to vertex using out.out, then you are only touching vertices. If you jump from vertex to edge to vertex using outE.inV, then you are touching vertices and edges.

If you want to ONLY get edges, then simply filter the final emitted path as such:

gremlin> g = TinkerGraphFactory.createTinkerGraph() ==>tinkergraph[vertices:6 edges:6] gremlin> g.v(1).outE.inV.outE.inV.path ==>[v[1], e[8][1-knows->4], v[4], e[10][4-created->5], v[5]] ==>[v[1], e[8][1-knows->4], v[4], e[11][4-created->3], v[3]]
gremlin> g.v(1).outE.inV.outE.inV.path.transform{it.findAll{it instanceof Edge}} ==>[e[8][1-knows->4], e[10][4-created->5]] ==>[e[8][1-knows->4], e[11][4-created->3]]

However, I suspect you are more interested in the named step approach. For instance:

gremlin> g.v(1).outE.as('a').inV.outE.as('b').inV.select ==>[a:e[8][1-knows->4], b:e[10][4-created->5]] ==>[a:e[8][1-knows->4], b:e[11][4-created->3]]

You can also get a Table data structure back if you want using table(). You can read more about this model here:


Good luck,
Marko.

--
 
 

Reply all
Reply to author
Forward
0 new messages