0

I am using Cosmos DB - Graph to store data and developing API to query graph db and return query results in below format. API can accept any node type and id as parameter and traverse through in & out edges to return nested vertex and edges.

{
    "nodes":[
        {"id":"1","name":"A"},
        {"id":"2","name":"B"},
        {"id":"3","name":"C1"},
        {"id":"4","name":"C2"},
        {"id":"5","name":"C3"},
        {"id":"6","name":"D1"},
        {"id":"7","name":"D2"},
        {"id":"8","name":"D3"}
    ],
    "edges":[
        {"source":"1","target":"2"},
        {"source":"2","target":"3"},
        {"source":"2","target":"4"},
        {"source":"2","target":"5"},
        {"source":"3","target":"6"},
        {"source":"4","target":"7"},
        {"source":"5","target":"8"}
    ]
}

Sample Graph:

Sample Graph

I am new to gremlin graph query and facing issue to traverse through graph. I got few samples to get in & out edges and looking for vertex query. I am planning to execute 4 queries to generate the above format:

For Edges

g.V().has('name', 'A').repeat(__.bothE().where(without('e')).store('e').otherV()).cap('e')
g.V().has('name', 'A').repeat(__.inE().where(without('e')).store('e').outV()).cap('e')

For Nodes

g.V().has('name', 'A').repeat(out()).until(outE().count().is(0)).simplePath()

I tried couple of sample query but not able to get all in & out vertex. I am looking for query that returns all vertex or any better solution to reduce the query to build the output in JSON format.

2 Answers2

0

This single query gives you the output you need:

g.V().has("name","C1").emit().repeat(bothE("e").simplePath()
  .sideEffect(project("source","target")
    .by(outV().id())
    .by(inV().id()).store("edges"))
  .otherV())
  .valueMap(true, "name").store("nodes").cap("nodes","edges")
Kfir Dadosh
  • 1,411
  • 9
  • 9
  • Thank you for providing query. It's giving me all the node regardless of current node e.g. if current node is C1 or C2 it always return all nodes and edges what if i need only incoming path e.g. if current node is C1 it should return A->B->C1->D1 (not C2->D2, C3->D3). – Brijen Shah Dec 06 '19 at 04:46
0

Based on your description and the comment below the other answer, I guess this is what you need:

g.V().has("name","C1").
  aggregate("n").
  union(outE().emit().repeat(inV().aggregate("n").outE()),
        inE().emit().repeat(outV().aggregate("n").inE())).
  project("source","target").
    by(outV().id()).
    by(inV().id()).fold().
  project("nodes","edges").
    by(select("n").
         by(unfold().
            project("id","name").
              by(id).
              by("name").
            fold())).
    by()

The result for this query run on your sample graph would be:

gremlin> g.V().has("name","C1").
......1>   aggregate("n").
......2>   union(outE().emit().repeat(inV().aggregate("n").outE()),
......3>         inE().emit().repeat(outV().aggregate("n").inE())).
......4>   project("source","target").
......5>     by(outV().id()).
......6>     by(inV().id()).fold().
......7>   project("nodes","edges").
......8>     by(select("n").
......9>          by(unfold().
.....10>             project("id","name").
.....11>               by(id).
.....12>               by("name").
.....13>             fold())).
.....14>     by().next()
==>nodes=[{id=3, name=C1}, {id=6, name=D1}, {id=2, name=B}, {id=1, name=A}]
==>edges=[{source=3, target=6}, {source=2, target=3}, {source=1, target=2}]
Daniel Kuppitz
  • 10,846
  • 1
  • 25
  • 34
  • Thanks Daniel for providing query. I tried connecting with Cosmos Db but it's failing with error: _Gremlin Query Execution Error: Project By: Next: The provided traverser of key "id" maps to nothing._ It's throwing an error at line 11: by("id"). – Brijen Shah Dec 09 '19 at 22:59
  • it's `by(id)`, not `by("id")`. `id` refers to `T.id` (http://tinkerpop.apache.org/javadocs/current/core/org/apache/tinkerpop/gremlin/structure/T.html#id). – Daniel Kuppitz Dec 10 '19 at 16:06