1

My initial logic of checking if an edge is present and creating an edge needs to query. Im trying to verify and create an edge in one instruction.

This query does not seem to work

ipdb> prop = self._graph.V('pppp').outE('friend').hasId('testEdge').as_('e').inV()
             .hasId('dddd').select('e').
             coalesce(__.property('testedder', 1111).fold().unfold(), 
                __.V('dddd'). as_('to_a').V('pppp').addE('friend').to('to_a')).
             toList()

1) The first part of the coalesce - updating the property of Edges work fine

2) The second part of the coalesce is either not being called or not working. It is working as an independent query. Does 'as' not work in anonymous traversals?

PS: Im using AWS Neptune

Stanislav Kralin
  • 11,070
  • 4
  • 35
  • 58
Kai
  • 953
  • 6
  • 16
  • 37

1 Answers1

3

You had the right idea but you needed some simplification. I'll try to do it in steps. First, whenever I see labelled steps, I try to see if there is a way to avoid using them. In this case, they can be factored out:

g.V('pppp').outE('friend').
  filter(hasId('testEdge').inV().hasId('dddd')).
  coalesce(__.property('testedder', 1111).fold().unfold(), 
           __.V('dddd'). as_('to_a').V('pppp').addE('friend').to('to_a'))

Readability of the traversal improves on those first two lines because the reader can immediately see that you want to find an edge given some criteria which was only implied by the step labeling approach. Next, I looked at coalesce(). As it stands, if filter() returns no edges then coalesce() will never get a chance to execute and that's why the second part of coalesce() never has an opportunity to work for you. So, let's clean that part up:

g.V(1).outE('knows').
  filter(hasId(6).inV().hasId(2)).
  fold().
  coalesce(unfold().property('testedder', 1111),
           V('dddd').as_('to_a').V('pppp').addE('friend').to('to_a'))

If it's not clear why the fold() and unfold() are where they are, you should check out my detailed explanation of the approach here. So, with fold() and unfold() where they should be, the coalesce() should now trigger both conditions depending on whether or not an edge passes the filter(). The first part of the coalesce() is fine, but the second could still use a bit of work as I'd again like to factor out the step labels if the aren't necessary:

g.V('pppp').outE('friend').
  filter(hasId('testEdge').inV().hasId('dddd')).
  fold().
  coalesce(unfold().property('testedder', 1111),
           addE('friend').from(V('pppp')).to(V('dddd')))

The above Gremlin assumes that you know "pppp" vertex exists. If you do not then you might try (as suggested by Daniel Kuppitz):

g.V('pppp').
  not_(outE('friend').hasId('testEdge').
       filter(inV().hasId('dddd')).
         property('testedder', 1111)).as('p').
  V('dddd').
    addE('friend').from('p')
stephen mallette
  • 45,298
  • 5
  • 67
  • 135
  • Thanks for the detailed response! Works for me. Only minor comment, AWS neptune doesnot support from/to(Vertex). It supports if labels are used. Initially i was trying to avoid fold as I had to use labels, which was why the fold ended up in a weird place – Kai Sep 27 '18 at 18:43
  • Hi Stanislav. Using something like `addE('test').to(V('123'))` should work fine with Neptune. Are you seeing an error? If so could you please share the query and the error? – Kelvin Lawrence Oct 03 '18 at 21:56
  • @KelvinLawrence you can see that here in the implementation differences https://docs.aws.amazon.com/neptune/latest/userguide/access-graph-gremlin-differences.html – Kai Oct 04 '18 at 05:44
  • Hi again @kairav - I tested that traversal on Neptune before I made the comment. What query are you trying to issue and are you doing it from the console or from code or maybe over the REST API? From the Gremlin console this works fine with Neptune: `g.V('3').addE('test').to(V('5'))` – Kelvin Lawrence Oct 14 '18 at 23:05
  • i tried `g.addE('test').from(V('3')).to(V('5')).next()` which doesn't work, maybe this is what he is referring to @KelvinLawrence – cryanbhu Oct 20 '18 at 13:56
  • 1
    How are you communicating with Neptune? That also works fine from the console. `gremlin> g.addE('test').from(V('3')).to(V('5')).next()` `==>e[00b34c66-73df-16ad-66cc-da4e04d61b61][3-test->5]` – Kelvin Lawrence Oct 21 '18 at 22:45
  • @KelvinLawrence i am using Python i.e. gremlin-python – cryanbhu Oct 26 '18 at 03:15
  • 1
    OK so using the Python GLV you need to prefix the V as follows: `g.V('3').addE('test').to(__.V('5')).next()` – Kelvin Lawrence Nov 01 '18 at 17:06
  • 1
    @cryanbhu ^^^^^ – Kelvin Lawrence Nov 01 '18 at 17:23