Inconsistent Traversal behaviour of cayley output


#1

Hi Guys

Sorry that I am putting too many questions these days. I am getting some unexpected response from the cayley while traversing the graph. I am using postgres as a backend database.

Example : I have added the below relationship from the write API of cayley -

Test1 RunsOn Test2
Test2 RunsOn Test3
Test3 DependsOn Test4
Test4 DependsOn Test5
Test5 BelongsTo Test6
Test6 Contains Test7
Test4 ConnectedTo Test8
Test5 ConnectedTo Test9

Url : http://10.236.220.137:64210/api/v1/write
Method : POST
Body :
[{
“subject”: “Test1”,
“predicate”: “RunsOn”,
“object”: “Test2”
},{
“subject”: “Test2”,
“predicate”: “RunsOn”,
“object”: “Test3”
},{
“subject”: “Test3”,
“predicate”: “DependsOn”,
“object”: “Test4”
},{
“subject”: “Test4”,
“predicate”: “DependsOn”,
“object”: “Test5”
},{
“subject”: “Test5”,
“predicate”: “BelongsTo”,
“object”: “Test6”
},{
“subject”: “Test6”,
“predicate”: “Contains”,
“object”: “Test7”
},{
“subject”: “Test4”,
“predicate”: “ConnectedTo”,
“object”: “Test8”
},{
“subject”: “Test5”,
“predicate”: “ConnectedTo”,
“object”: “Test9”
}]

But , when I am traversing the cayley database to get the response I am getting four extra relationship which one is not inserted by the api and this one is not even exist in the database as well.

Query :

var path = g.M().Both();
g.V(“Test1”).FollowRecursive(path).ForEach( function(v){
g.V(v.id).OutPredicates().ForEach( function®{
g.V(v.id).Out().ForEach( function(t){
var node = {
source: v.id,
relation : r.id,
target: t.id
}
g.Emit(node)
})
})
})

Response :
{
“result”: [
{
“relation”: “RunsOn”,
“source”: “Test2”,
“target”: “Test3”
},
{
“relation”: “RunsOn”,
“source”: “Test1”,
“target”: “Test2”
},
{
“relation”: “DependsOn”,
“source”: “Test3”,
“target”: “Test4”
},
{
“relation”: “DependsOn”,
“source”: “Test4”,
“target”: “Test5”
},
{
“relation”: “DependsOn”,
“source”: “Test4”,
“target”: “Test8”
},
{
“relation”: “ConnectedTo”,
“source”: “Test4”,
“target”: “Test5”
},
{
“relation”: “ConnectedTo”,
“source”: “Test4”,
“target”: “Test8”
},
{
“relation”: “BelongsTo”,
“source”: “Test5”,
“target”: “Test6”
},
{
“relation”: “BelongsTo”,
“source”: “Test5”,
“target”: “Test9”
},
{
“relation”: “ConnectedTo”,
“source”: “Test5”,
“target”: “Test6”
},
{
“relation”: “ConnectedTo”,
“source”: “Test5”,
“target”: “Test9”
},
{
“relation”: “Contains”,
“source”: “Test6”,
“target”: “Test7”
}
]
}

Note : It should have return only eight relationship as we have inserted the same number of relationship via the rest api.

I am not able to understand the behavior. Can someone please help me to understand the things.

Thanks in advance.


#2

Hi @dennwc

Can you please help me out to resolve this issue asap as its a urgent requirement.

Thanks in advance.


#3

I will check it in few minutes


#4

It looks like you are doing internal queries without accounting for previous results:

g.V(v.id).OutPredicates().ForEach( function(r){
  g.V(v.id).Out().ForEach( function(t){
    var node = {
    source: v.id,
    relation : r.id,
    target: t.id
    }
    g.Emit(node)
  })
})

Note this part: g.V(v.id).Out(). It tells “traverse from id via ANY relation”, and then you emit it as if it only belongs to r.id predicate: relation : r.id,.

You should use g.V(v.id).Out(r.id) to force that only certain predicates are traversed. Also not, that you can tag predicates inline: f.V().Out(nil, "pred").


#5

Ohhhh Mighty @dennwc !!

Thank you so much @dennwc. You have just saved me.