0

I'm trying to compose one query to get all incoming and outgoing vertices, including their edges and directions, which would however return those vertices without edges as well.

I was able to work around the problem for now by forcing everything to have at least one edge, but it's something I'd like to avoid.

Maybe worth noting that I use the Graph API of Azure CosmosDB: https://learn.microsoft.com/en-us/azure/cosmos-db/gremlin-support

This is the query I'm using to return all vertices with their edges and related vertices:

g.V().hasLabel('User').as('User').bothE().as('Edge').otherV().as('RelatedObject').path()

I got this from: Gremlin get all incoming and outgoing vertex, including their edges and directions

This query produces the result which I am able to easily parse in a C# application later, however this query doesn't return vertices which don't have edges.

Any ideas?

EDIT

The closest I've got is this:

g.V().hasLabel("User").as("User").map(bothE().otherV().fold()).as("RelatedObjects").select("User", "RelatedObjects")

However this approach doesn't display edges between User and RelatedObjects. I also need edges to be able to map these related objects to parent object properly.

Dejan Janjušević
  • 3,181
  • 4
  • 41
  • 67

4 Answers4

4

I think you can drop all the step labels and use of side-effects - just use project():

gremlin> g.V().hasLabel('person').
......1>   project('user','edges','relatedVertices').
......2>     by().
......3>     by(bothE().fold()).
......4>     by(both().fold())
==>[user:v[1],edges:[e[9][1-created->3],e[7][1-knows->2],e[8][1-knows->4]],relatedVertices:[v[3],v[2],v[4]]]
==>[user:v[2],edges:[e[7][1-knows->2]],relatedVertices:[v[1]]]
==>[user:v[4],edges:[e[10][4-created->5],e[11][4-created->3],e[8][1-knows->4]],relatedVertices:[v[5],v[3],v[1]]]
==>[user:v[6],edges:[e[12][6-created->3]],relatedVertices:[v[3]]]
stephen mallette
  • 45,298
  • 5
  • 67
  • 135
2

I don't have you graph to test with but this general pattern should work for you I think.

g.withSideEffect('x', [] as Set).                        
     V().hasLabel("user").store('x').                                    
     bothE().store('x').                                  
     otherV().store('x').                                 
     cap('x')

Edited to not use Set

g.withSideEffect('x', []).                        
     V().has('code',"AUS").store('x').                                    
     bothE().store('x').                                  
     otherV().store('x').                                 
     cap('x').unfold().dedup().fold() 
Kelvin Lawrence
  • 14,674
  • 2
  • 16
  • 38
  • Doesn't seem to work with Microsoft.Azure.Graphs: Gremlin Query Compilation Error: Script compile error: Unsupported groovy language rule: 'type' text: 'Set' @ line 1, column 29. I don't think `withSideEffect` is supported either. – Dejan Janjušević Jan 13 '18 at 21:36
  • That's too bad. I ran it on my laptop with TinkerGraph/Gremlin Console at the 3.3 level using my own graph and it did the job. – Kelvin Lawrence Jan 13 '18 at 21:39
  • If by chance `withSideEffect` is supported you can just use a list instead of a Set ` g.withSideEffect('x', []). V().has('code',"AUS").store('x'). bothE().store('x'). otherV().store('x'). cap('x') ` – Kelvin Lawrence Jan 13 '18 at 22:32
  • Unfortunately that was the first thing I've tried after the first one failed... But I gotta give you +1 for effort. – Dejan Janjušević Jan 13 '18 at 22:46
1

Try this

g.V().hasLabel("User").as("User").bothE().as(“edges”).map(select(“edges”).inV().fold()).as("RelatedObjects").select("User", "RelatedObjects",”edges”)

Jayanta Mondal
  • 436
  • 2
  • 5
  • Interesting approach, however it only shows one edge from each user. I tried to add `.fold()` step after `.bothE()` step but that caused an exception in Microsoft.Azure.Graphs library. – Dejan Janjušević Jan 13 '18 at 20:26
  • Actually it works (it just displays one `User` for each edge it has but it's good enough)! – Dejan Janjušević Jan 13 '18 at 20:47
  • Sorry, it actually still ignores vertices which have no edges... I tried this one: `.as('User').bothE().as('Edge').map(select('Edge').otherV()).as('RelatedVertex').select('Vertex', 'Edge', 'RelatedVertex')`. Must be too tired. – Dejan Janjušević Jan 13 '18 at 21:20
1

This was the way it works with CosmosDB:

g.V().hasLabel("User")
    .as('Vertex') <------------------- alias for all users
    .map(bothE().fold())
    .as('Edges')
    .map(select('Vertex') <----------- this was the key. Map from the first step
        .bothE().otherV().fold())
    .as('RelatedVertices')
    .select('User', 'Edges', 'RelatedVertices')

Unfortunately, the withSideEffect doesn't seem to be supported by Microsoft.Azure.Graphs library, so the below way, proposed by Kelvin which seems more elegant can't be used:

g.withSideEffect('x', [] as Set).                        
     V().hasLabel("user").store('x').                                    
     bothE().store('x').                                  
     otherV().store('x').                                 
     cap('x')
Dejan Janjušević
  • 3,181
  • 4
  • 41
  • 67