Accessing and compare properties of the stored edge in traversal

206 Views Asked by At

I have following graph model:

enter image description here

I want to select user, who has performed action via the controller. The performed-by edge contains used_user_key property, that i want to use in order to select the called-by edge connected to the required user on the following condition: called-by.user_key == performed-by.used_user_key property.

I store performed-by in action_edge and trying to use stored value in has step.

Problem: has('user_key', select('action_edge').values('used_user_key')) yields random edge.

Question: How should i get/reference property from the stored edge in a has step?

GraphDB: JanusGraph 0.5.2 gremlinpython: 3.5.0

Python snippet for reproducing the issue:

user_a = g.addV('user').property('name', 'a').next()
user_b = g.addV('user').property('name', 'b').next()
user_c = g.addV('user').property('name', 'c').next()
controller = g.addV('controller').property('name', 'controller').next()
action = g.addV('action').property('name', 'action').next()

g.V(user_a).as_('to').V(controller).as_('from') \
    .addE('called-by') \
    .property('user_key', 'user_a') \
    .to('to') \
    .next()

g.V(user_b).as_('to').V(controller).as_('from') \
    .addE('called-by') \
    .property('user_key', 'user_b') \
    .to('to') \
    .next()

g.V(user_c).as_('to').V(controller).as_('from') \
    .addE('called-by') \
    .property('user_key', 'user_c') \
    .to('to') \
    .next()

g.V(controller).as_('to').V(action).as_('from') \
        .addE('performed-by') \
        .property('used_user_key', 'user_a') \
        .to('to') \
        .next()

# Works as expected!
user_perming_the_action = g.V(action).outE('performed-by').as_('action_edge').inV() \
    .outE('called-by').has('user_key', 'user_a').inV() \
    .next()
assert user_a.id == user_perming_the_action.id

# Selects random user - ignores all action_edge.used_user_key value
user_perming_the_action = g.V(action).outE('performed-by').as_('action_edge').inV() \
    .outE('called-by').has('user_key', select('action_edge').values('used_user_key')).inV();

# Why it yield 3 instead of 1 edge?
assert user_perming_the_action.clone().count().next() == 3
# Returns random user
assert user_a.id == user_perming_the_action.clone().next().id

Thanks for you help in advance!

1

There are 1 best solutions below

0
On

After some research, i have found following solution to the problem:

    user_perming_the_action = g.V(action).outE('performed-by').as_('action_edge').inV() \
        .outE('called-by').where(eq('action_edge')).by('user_key').by('used_user_key').inV() \
        .next()
    assert user_a.id == user_perming_the_action.id

I am comparing edges with where on properties with different names by using two by modulators.