Gremlin: How do you find vertices without a particular edge?
Asked Answered
T

4

7

I've been looking at the Gremlin graph language, and it appears very powerful. However, whilst running through what it can do to evaluate it against requirements, I came across a case that I can't seem to complete.

Assuming Gremlin is started, and using its example database:

gremlin> g = TinkerGraphFactory.createTinkerGraph()
...
gremlin> g.V.out('knows')
==>v[2]
==>v[4]

So this shows vertices that have an edge of 'knows'.

However, I want to find vertices that do not have edges of 'knows'. Something like:

gremlin> g.V.outNot('knows')
==>v[3]
==>v[5]
==>v[6]

How do I find these vertices?

(Edited to make the output correct)

Tamworth answered 3/4, 2014 at 12:1 Comment(0)
S
6

I interpret this question several ways, but perhaps this is what you are after. One way would be to do:

gremlin> g = TinkerGraphFactory.createTinkerGraph()    
==>tinkergraph[vertices:6 edges:6]
gremlin> g.V.outE.hasNot('label','knows')
==>e[9][1-created->3]
==>e[12][6-created->3]
==>e[10][4-created->5]
==>e[11][4-created->3]
gremlin> g.V.outE.hasNot('label','knows').inV
==>v[3]
==>v[3]
==>v[5]
==>v[3]

Note that label and id are both recognized as properties:

gremlin> g.V.has('id',"1")
==>v[1]
gremlin> g.E.map("label","id")
==>{id=10, label=created}
==>{id=7, label=knows}
==>{id=9, label=created}
==>{id=8, label=knows}
==>{id=11, label=created}
==>{id=12, label=created}

Another way to consider this question would be to find a list of vertices that don't have a "knows" edge:

gremlin> g.V.filter{!it.bothE('knows').hasNext()}    
==>v[3]
==>v[6]
==>v[5]
Semitrailer answered 3/4, 2014 at 14:1 Comment(7)
Thank you, the lesson here is that the "properties" on edges are "labels", so it can be used with hasNot() and so on. But that doesn't quite get back to which vertices have no edges labelled "knows", i.e. an expression that returns vertices 1, 3, 5 and 6...Tamworth
Yes, basically an edge label is recognized as a property and can thus work properly with has()/hasNot operations. the same can be said of the element id. Included other examples in my answer to demonstrate.Semitrailer
Ok - but that still doesn't address the problem - let me rephrase. The solution you have filters the relationships (edges) that exist. The 'hasNot(...)' returns vertices (or edges) that are not 'knows'. But what I want is the absence of edges, as opposed to filtering existing edges. So I want "notOut(<condition>)" - does that make sense?Tamworth
sorry if i'm still not following. Are you saying you want to find vertices that don't have a "knows" edge? If so, see my updated answer. btw, i think your example in your question is off because v[1] has a "knows" edge.Semitrailer
You are right - my mistake. Yes, that's now what I'm after, thanks!Tamworth
The later version of Gremlin does not seem to have hasNot function with 2 arguments. Is there another way to check this?Olmstead
You can do outE().not(hasLabel('knows'))Semitrailer
P
4

If you are looking for the Groovy syntax (which can be used by AWS Neptune with their notebooks for example). You can build your query like this

g.V().not(outE('filtered_relationship'))
Paul answered 27/1, 2021 at 14:3 Comment(0)
G
0

i am using gremlin over orientdb and this is working for me; just prefix edge label with 'out_'

g.V.hasNot('out_knows');
Gile answered 30/8, 2015 at 13:2 Comment(0)
Y
0
g.V().
hasLabel('nodel_label').
not(filter(__.in('edge_label')))
Yerga answered 20/9, 2022 at 14:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.