jbmusso / grex

JavaScript graph database client for TinkerPop2 Rexster
MIT License
46 stars 12 forks source link

how can I addVertex only if not exists and addEdge only if not exists using grex script in one query for execute #51

Open ellavs1 opened 10 years ago

jbmusso commented 10 years ago

1) Regarding the creation of vertices if they do not exists, your application will have to implement the logic or alternatively you may have to rely on indices depending on the use case and the graph database used.

a) If you want a get or create behavior, a working example can be found here: http://thinkaurelius.com/2014/05/29/powers-of-ten-part-i/ Basically, you'll have to do something along these lines:

getOrCreate = { id ->
  def p = g.V('userId', id)
  if (p.hasNext()) ? p.next() : g.addVertex([userId:id])
}

b) If you want a create or throw behavior, say because you want some property values to be unique (for example, an email property guaranteed unique across all user vertices), you'll have to configure an index in your database to handle this for you. Titan does this with [composite indices](http://s3.thinkaurelius.com/docs/titan/0.5.1/indexes.html#_composite_index and the unique constraint).

2) Regarding "unique" edge creation:

a) Your graph database may support cardinality constrains for edges. If you're using Titan graph database, you can explicitly define edge label multiplicity constrains in your schema. I'm unsure if other graph vendors offer such feature.

b) Alternatively, you'll have to check for the existence of an already present edge. Although edges may look the same (ie. have the exact same properties), they'll always differ by their ids. Have a look at the duplicate edges recipe from gremlindocs.com which uses TinkerPop's ElementHelper.haveEqualProperties() method.

Regarding gRex, any of the above can done in a single multiline query.

ellavs1 commented 10 years ago

thanks, but grex does not have hasNext() function.

i tried :

var v1 = query.var((g.V('uid','123').count() > 0)?g.V('uid','123').next():g.addVertex({"uid":"123"}));

but it always do g.addVertex , I run it in gremlin rexster command line and it works,but in grex it does work good, it does addVertex inseted of get if it exists.

jbmusso commented 10 years ago

You're right, you'll have to use the printf mode of gRex and issue direct string: https://github.com/gulthor/grex#building-a-gremlin-script-with-string-formatting-and-bound-parameters

This is the recommended way to get you out of trouble when a method is missing in gRex. I'll add the hasNext() method when I have some time, thanks for pointing that out!

syedhassaanahmed commented 6 years ago

You can do it directly in Gremlin like this g.v('userId').fold().coalesce(unfold(), addV('users').property('id', 'userId'))