Search code examples
gremlintinkerpop3

Gremlin: Count outbound edges with a given label and property value


I have a graph where vertices have several outbound edge types and each of those edge types have properties. I want to get a count of outbound edges from each vertex but limit the count to edges with a certain label and property value.

So far I have:

g.V().hasLabel("vertexLabel").as("source")
    .outE("edgeLabel").has("edgeProp", "propValue").as("edge")
    .select("source", "edge")

This gives me a list of each source vertext and each outgoing edge with the correct label and property. What I want to do is reduce this to a single entry for each source vertex and count of the number of outbound edges. However I cannot seem to get groupCount to work in combination with outE. The closest I have got is:

g.V().hasLabel("vertexLabel").as("source").out("edgeLabel").groupCount()

This gives me count by source vertex but includes all the edges with that label regardless of what property values they have.

I know this probably needs a group().by() step but I am not sure how to form it.

Thanks in advance.


Solution

  • Using the "modern" toy graph from TinkerPop, I think you can best express this by using project():

    gremlin> g.V().hasLabel('person').
    ......1>   project('source','count').
    ......2>     by().
    ......3>     by(outE('created').has('weight',gt(0.5)).count())
    ==>[source:v[1],count:0]
    ==>[source:v[2],count:0]
    ==>[source:v[4],count:1]
    ==>[source:v[6],count:0]
    

    You can do this with groupCount() as well but it feels a bit more awkward to me:

    gremlin> g.V().hasLabel('person').
    ......1>   outE('created').
    ......2>   has('weight',gt(0.5)).
    ......3>   groupCount().
    ......4>     by(inV())
    ==>[v[5]:1]
    

    Note you lose the "0" values in this case because the edges get filtered away prior to groupCount(). You could also go with group() but I don't think it reads as nicely as project():

    gremlin> g.V().hasLabel('person').
    ......1>   group().
    ......2>     by().
    ......3>     by(outE('created').
    ......4>        has('weight',gt(0.5)).count())
    ==>[v[1]:0,v[2]:0,v[4]:1,v[6]:0]