-2

I'm using gremlin and have the statement below. I want to:

  • create a vertex if one does not exist
  • create another vertex if one does not exist
  • create an edge between the verticies

The edge doesn't get created. I'd really appreciate help with the logic/approach here.

    g.V().has('User','refId','435').
        fold().coalesce(unfold(),addV(label, 'User').
    property('name','John Smith').property('refId','435'))
        .as('user').
        V().has('JobTitle','name','Advisor').
        fold().coalesce(unfold(),addV(label,'JobTitle').
property('name','Advisor'))
.as('jobtitle').
    addE('REGISTERED_AS').from('user').to('jobtitle')
  • Please could you add the complete query (it is truncated) and it would be good in general to include a description of the backend graph database you are using and any additional examples and commentary to make the question more complete. – Kelvin Lawrence Mar 20 '20 at 14:49
  • @KelvinLawrence I've updated above. Issue with this is the edge is not created between the vertices. – Silvertooth Mar 21 '20 at 00:24
  • You cannot just provide a list of strings to `addV()`. You need to use the `property()` step the way you were in your previous example. Also it would be much easier to read your query if you split it up over multiple lines. – Kelvin Lawrence Mar 21 '20 at 14:59
  • @KelvinLawrence thanks . I've updated that however the edge still does not get created. Can you help fix this please? – Silvertooth Mar 21 '20 at 21:58

2 Answers2

1

Given your most recent comment on Kfir's answer that includes your latest code, I think that there are several problems to correct with your approach. First note that addV() does not take a long list of labels and properties. I'm surprised that didn't generate an error for you. addV() just takes the vertex label as an argument and then you use property() to provide the associated key/value pairs.

g.V().has('User', 'refId', '435').
      fold().
      coalesce(unfold(), 
               addV('User').
                 property('name', 'John Smith').property('refId', '435').property('firstName', 'John').
                 property('lastName', 'Smith').property('JobTitle', 'Chief Executive Officer')).as('user').
      V().has('JobTitle', 'name', 'Advisor').
      fold().
      coalesce(unfold(), addV(label, 'JobTitle', 'name', 'Advisor')).as('jobtitle').
      V().
      addE('REGISTERED_AS').
        from('user').
        to('jobtitle')

There is an extra V() right before addE() which would basically call addE() for every vertex you have in your graph rather than just for the one vertex to which you want to add an edge.

g.V().has('User', 'refId', '435').
      fold().
      coalesce(unfold(), 
               addV('User').
                 property('name', 'John Smith').property('refId', '435').property('firstName', 'John').
                 property('lastName', 'Smith').property('JobTitle', 'Chief Executive Officer')).as('user').
      V().has('JobTitle', 'name', 'Advisor').
      fold().
      coalesce(unfold(), addV(label, 'JobTitle', 'name', 'Advisor')).as('jobtitle').
      addE('REGISTERED_AS').
        from('user').
        to('jobtitle')

So, now things look syntax correct but there is a problem and it stems from this:

gremlin> g.V(1).as('x').fold().unfold().addE('self').from('x').to('x')
The provided traverser does not map to a value: v[1]->[SelectOneStep(last,x)]
Type ':help' or ':h' for help.
Display stack trace? [yN]

The path information in the traversal is lost after the a reducing step (i.e. fold()) so you can't select back to "x" after that. You need to reform your traversal a bit to not require the fold():

g.V().has('User', 'refId', '435').
      fold().
      coalesce(unfold(), 
               addV('User').
                 property('name', 'John Smith').property('refId', '435').property('firstName', 'John').
                 property('lastName', 'Smith').property('JobTitle', 'Chief Executive Officer')).as('user').
      coalesce(V().has('JobTitle', 'name', 'Advisor'),
               addV('JobTitle').property('name', 'Advisor')).as('jobtitle').
      addE('REGISTERED_AS').
        from('user').
        to('jobtitle')

That really just means using coalesce() more directly without the fold() and unfold() pattern. You really only need that pattern at the start of a traversal to ensure that a traverser stays alive in the stream (i.e. if the user doesn't exist fold() produces an empty list which becomes the new traverser and the traversal will continue executing).

stephen mallette
  • 45,298
  • 5
  • 67
  • 135
0

The question code is partial. Some alignment would help.

Nevertheless, I think your problem is in the as('jobtitle'), which is inside the coalesce statement. That is, if the vertex exists, we don't get to the second traversal and the as statement is not executed. Same for the as('user').

To solve, just move the as statements outside the coalesce.

Kfir Dadosh
  • 1,411
  • 9
  • 9
  • Thanks for this @Kfir Dadosh. I've changed to move the statement outside however still doesn't create the edge. Further thoughts? Here's the latest: g.V().has('User','refId','435').fold().coalesce(unfold(),addV(label, 'User', 'name','John Smith', 'refId', '435','firstName','John' ,'lastName','Smith','JobTitle','Chief Executive Officer')).as('user').V().has('JobTitle','name','Advisor').fold().coalesce(unfold(),addV(label, 'JobTitle', 'name','Advisor')).as('jobtitle').V().addE('REGISTERED_AS').from('user').to('jobtitle') – Silvertooth Mar 21 '20 at 00:20
  • can you help with the query above please? – Silvertooth Mar 21 '20 at 21:59