dav04
dav04

Reputation: 19

Gremlin python coalesce for edges

I have written a script to avoid creating duplicates for vertex and edges but I have some troubles with edges. This is the script:

g.V().has('dog', 'name', 'pluto').fold().\
    coalesce(__.unfold(), __.addV('dog').property('name', 'pluto')).store('dog').\
    V().has('person', 'name', 'sam').fold().\
    coalesce(__.unfold(), __.addV('person').property('name', 'sam')).store('person').\
    select('person').unfold().\
    coalesce(__.outE('has_dog').where(__.inV().has(T.id, __.select('dog').unfold().id())),
             __.addE('has_dog').to(__.select('person').unfold())).toList()

With this, I create the new two vertex and the new edge. If I execute it again, no new vertex and edge is created. For now all it's ok.

If I change 'pluto' with 'charlie' to create a new 'dog' vertex, this script creates the new vertex but return the previous edge created with 'pluto'. So if that 'person' already has that relationship, the script not creates a new one.

The thing I don't understand, it's that the code

__.select('dog').unfold().id()

should return the id of the new/old 'dog' vertex and check if the edge with 'person' exists. If I execute that script to get the id and I replace that script with the id, for example

__.outE('has_dog').where(__.inV().has(T.id, 42))

the script works correctly and creates the edge with the new 'dog' vertex.

Why with the script to get id doesn't work but with the integer works? It's no sense because I should have the same result.

Thanks.

Upvotes: 1

Views: 309

Answers (1)

Kelvin Lawrence
Kelvin Lawrence

Reputation: 14391

The issue you have run into is that a has step cannot take an arbitrary traversal but a where step can. You just need to reformulate the has step as a where step. An arbitrary traversal inside a has step is treated as "true" if it returns any result. This is one of those Gremlin things that looks as if it should work but actually does not.

Here is a contrived example that shows the where...by pattern that should be helpful in your case.

gremlin> g.V(3).as('x').V().where(eq('x')).by(id)
==>v[3]

As you are using store the where step becomes something like this

gremlin> g.V(3).store('x').V().where(eq('x')).by(id).by(unfold().id())
==>v[3] 

So the line in your code will end up something like this

filter(__.inV().where(eq('dog')).by(T.id).by(unfold().id()))

Upvotes: 1

Related Questions