1

I have a vertex that has a 'title' property. I have other vertices that have outgoing edges that have multiple properties. I'm trying to find vertices that have outgoing edges where the 'title' property value is a property key on the edge.

For example Vertex A has property {'title': ['lebron']} and Edge B has property {'lebron': 'basketball'}.

This is the example graph I have:

g.addV('person').property(id, 'bob')
g.addV('person').property(id, 'alice').addE().to(__.V('bob')).property('lebron', 'basketball')
g.addV('player').property('title', 'lebron').addE().from(__.V('bob'))

This is the query I currently came up with that isn't working:

   g
    .V('alice')
    .outE()
    .as('b')
    .otherV()
    .hasId('bob')
    .as('c')
    .select('b')
    .properties()
    .key()
    .fold()
    .as('k')
    .select('c')
    .outE()
    .otherV()
    .has('title', within('k')))
    .valueMap('title')
    .toList(); 
Kyano
  • 174
  • 1
  • 8

2 Answers2

1

Try this:

g
.V('alice')
.outE()
.as('b')
.otherV()
.hasId('bob')
.as('c')
.select('b')
.aggregate('keys').by(properties().key())
.select('c')
.out()
.where(values().where(within('keys')))
.valueMap('title')
.toList()
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • You almost got it! I modified it slightly to this and it worked, thank you very much: Instead of `.aggregate('keys').by(properties().key())` I used, `.properties().key().aggregate('keys')` – Kyano Jun 28 '22 at 14:39
1

Here's likely a more "Gremlin-othic" approach. Gremlin is meant to be an imperative query language, so the best approach is to try to "find-then-filter". Instead of using as() and select() statements and jumping around everywhere, it is better to make your path/traversal, label things along the way, and then filter at the very end.

g.V('alice').outE('edge').as('b').inV().hasId('bob').out().
    where(eq('b')).
        by(values('title')).
        by(properties().key()).
    valueMap()

This approach uses the where()-by() pattern, which in this case takes two by() modulators. The first modulating the values coming into the where() statement (the vertices found by the last out()) and the second by() modulates what is inside of the where() statement (the property keys of the edge).

More on where()-by() here: https://kelvinlawrence.net/book/Gremlin-Graph-Guide.html#whereby

Taylor Riggan
  • 1,963
  • 6
  • 12
  • I'm using aws-neptune and unfortunately inV() doesn't work there. – Kyano Jun 28 '22 at 14:41
  • Tried it with otherV and it didn;t work for me – Kyano Jun 28 '22 at 14:48
  • inV() should work on Neptune. The query above ran on a Neptune cluster. What programming language/Gremlin library are you using? – Taylor Riggan Jun 28 '22 at 15:11
  • You're correct I just tried it again and it works fine. If I ever come across an error with it I'll let you know, thanks! – Kyano Jun 28 '22 at 18:24
  • This is the query that I tried on my neptune cluster with gremlin js v3.6.0 and it's returning a null value: `g?.V('alice').outE('edge').as('b').inV().hasId('bob').out().where(P.eq('b')).by(__.values('title')).by(__.properties().key()).valueMap().next();` – Kyano Jun 28 '22 at 18:29
  • Likely that you need to change the 'edge' label of the outE() to fit whatever label you're using for edges. Also note, the latest version of Neptune only supports up to version 3.5.2 of TinkerPop/Gremlin. – Taylor Riggan Jun 29 '22 at 02:24
  • Thanks for the heads up. I changed the 'edge' tag but it still yields a null value. – Kyano Jun 29 '22 at 09:38