1

Using Gremlin, I can create a vertex in an Azure Cosmos DB graph by issuing

g.addV('the-label').property('id', 'the-id')

and subsequently find it using

g.V('the-label').has('id', 'the-id')

However, I haven't found a way to issue a query that will insert the node if it is missing, and just get the reference to it if it already exists. Is there a way?


My concrete use case is that I want to add an edge between two nodes, regardless of whether those nodes (or the edge, for that matter) exist already or not, in a single query. I tried this upsert approach, but apparently Cosmos DB does not support Groovy closures, so it won't work.

Tomas Aschan
  • 58,548
  • 56
  • 243
  • 402

2 Answers2

7

The "upsert pattern" is relatively well defined and accepted at this point. It is described here. If you want to extend that to also add an edge, that's possible too:

g.V().has('event','id','1').
  fold().
  coalesce(unfold(),
           addV('event').property('id','1')).as('start').
  coalesce(outE('link').has('id','3'),
           coalesce(V().has('event','id','2'), 
                    addV('event').property('id','2')).
                    addE('link').from('start').property('id','3'))

If that looks a bit complex you can definitely simplify with a Gremlin DSL (though I'm not sure that CosmosDB supports Gremlin bytecode at this point). Here's an example with even more complex upsert logic simplified by a DSL. It's discussed in this blog post in more detail.

UPDATE: As of TinkerPop 3.6.0, the fold()/coalesce()/unfold() pattern has been largely replaced by the new steps of mergeV() and mergeE() which greatly simplify the Gremlin required to do an upsert-like operation.

stephen mallette
  • 45,298
  • 5
  • 67
  • 135
  • Current Cosmos does not have support for bytecode, so no DSL, but I have been told they are working on it – bechbd May 16 '18 at 11:51
0

Please look at this.

http://tinkerpop.apache.org/docs/current/reference/#coalesce-step

You can try

g.Inject(0).coalesce(__.V().has('id', 'the-id'), addV('the-label').property('id', 'the-id'))

btw, you won't able to find the vertex using g.V('the-label').has('id', 'the-id').

g.V() accepts vertex id as parameters and not vertex labels.

Jayanta Mondal
  • 436
  • 2
  • 5