Reputation: 157
I have an orientdb graph database setup with User as vertex and Friend as edge.
2 Users are friends if they have 2 edges with each other:
u1 --Friend --> u2 and u2 -- Friend --> u1
How can I suggest friends of friends to u1 with Gremlin and make sure those people are not current friends of u1, with a single chain of Gremlin functions?
Here's my Gremlin code so far, but I want to filter out vertices already friends with u1:
u1.out('Friend').out('Friend').dedup()
I tried this but doesn't seem to work:
u1.out('Friend').out('Friend').dedup().filter{ it!= u1.out('Friend')}
Thank you for your help :).
Upvotes: 1
Views: 802
Reputation: 1552
I propose that you also sort the recommendations by some property, e.g. the number of paths of length 2 from the start user to the recommended user and hence apply basic collaborative filtering as proposed on the gremlin github home page.
Applied to your problem we could write:
m = [:]; known = [u1]; u1.out('friend').aggregate(known).out('friend').except(known).groupCount(m)
m = m.sort{-it.value}
This gives you a map m
ordered descending by the values which are the number of distinct paths of length 2 and the vertices of the users recommended as friends to user u1
as keys.
Hereafter an example:
g = new TinkerGraph()
u1 = g.addVertex('u1')
u2 = g.addVertex('u2')
u3 = g.addVertex('u3')
u4 = g.addVertex('u4')
u5 = g.addVertex('u5')
g.addEdge(u1,u2,'friend')
g.addEdge(u2,u1,'friend')
g.addEdge(u2,u3,'friend')
g.addEdge(u3,u2,'friend')
g.addEdge(u1,u5,'friend')
g.addEdge(u5,u1,'friend')
g.addEdge(u5,u4,'friend')
g.addEdge(u4,u5,'friend')
g.addEdge(u2,u4,'friend')
g.addEdge(u4,u2,'friend')
g.addEdge(u5,u2,'friend')
g.addEdge(u2,u5,'friend')
The content of the map after the proposed query for user u1
is:
gremlin> m
==>v[u4]=2
==>v[u3]=1
Maybe you also need to think about the impact on the query result of directed friendship edges without the corresponding edge in the opposite direction …
Upvotes: 4