Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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 this issue Oct 20, 2014 · 4 comments

Comments

@ellavs1
Copy link

ellavs1 commented Oct 20, 2014

No description provided.

@jbmusso
Copy link
Owner

jbmusso commented Oct 20, 2014

  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).

  1. 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
Copy link
Author

ellavs1 commented Oct 20, 2014

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
Copy link
Owner

jbmusso commented Oct 20, 2014

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
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants