Murilo Maciel Curti
Murilo Maciel Curti

Reputation: 3141

Azure Cosmos Graph nest edge vertex in a vertex property

I have two vertex:

1) Vertex 1: { id: 1, name: “john” }

2) Vertex 2: { id: 2, name: “mary” }

There is an edge from 1 to 2 named “children”.

Is it possible to return 2 nested in 1 using gremlin like this?

  { 
    id: 1, 
    name: “john”,
    children: { id: 2, name: “mary” }
  }

Thank you!

My solution with an amazing help of @noam621 ---------------------------------


g.V(1)
.union( valueMap(true),
        project('children').by( coalesce( out('children').valueMap(true).fold() , constant([]))),
        project('parents').by( coalesce( out('parents').valueMap(true).fold() , constant([])))
)
.unfold().group().by(keys).by(select(values))

It returns the following object:

{ 
    id: 1, 
    name: [ “john” ],
    children: [ { id: 2, name: [ “mary” ] } ],
    parents: []
}

.union with project are the key to merge all objects in one object. valueMap(true).fold() is fundamental to get all objects in the edge and coalesce helps with a default value if the edge doesn't return any vertex.

Due to some Azure Cosmos gremlin limitations is only possible to get values as array values. Thus I finalized the object formatting in my application code. It's ok for now.

Thank you!

Upvotes: 1

Views: 298

Answers (1)

noam621
noam621

Reputation: 2856

You can do it by using the project step for both vertexes:

g.V(1).project('id', 'name', 'children').
    by(id).
    by('name').
    by(out('children').
      project('id', 'name').by(id).
        by('name'))

example: https://gremlify.com/3j


query with valueMap:

g.V(1).union(
    valueMap().
      with(WithOptions.tokens).by(unfold()),
    project('children').
      by(out('children').
        valueMap().
          with(WithOptions.tokens).by(unfold()))
  ).unfold().
  group().by(keys).
    by(select(values))

if valueMap().with(WithOptions.tokens) not supported in Cosmos use valueMap(true) instead

Upvotes: 2

Related Questions