Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
512 views
in Technique[技术] by (71.8m points)

tinkerpop - Gremlin - Choose one item at random

Consider me as 'user' 1. The aim of the query is to get the posts 'posted' by the people I follow and for each of those posts check:

  1. Whether it has been liked by me
  2. Whether it has been liked by anyone else that I follow and if yes choose one of those users at random to return

Sample data:

g.addV('user').property('id',1).as('1')
  addV('user').property('id',2).as('2').
  addV('user').property('id',3).as('3').
  addV('user').property('id',4).as('4').
  addV('post').property('postId','post1').as('p1').
  addV('post').property('postId','post2').as('p2').
  addE('follow').from('1').to('2').
  addE('follow').from('1').to('3').
  addE('follow').from('1').to('4').
  addE('posted').from('2').to('p1').
  addE('posted').from('2').to('p2').
  addE('liked').from('1').to('p2').
  addE('liked').from('3').to('p2').
  addE('liked').from('4').to('p2').iterate()

Query: (As answered here: Graph/Gremlin for social media use case) g.V().has('id',1).as('me').out('follow').aggregate('followers').out('posted').group().by('postId').by(project('likedBySelf','likedByFollowing').by(__.in('liked').where(eq('me')).count()).by(__.in('liked').where(within('followers')).order().by(shuffle).values('id').fold()))

Output:

[post1:[likedBySelf:0,likedByFollowing:[]],post2:[likedBySelf:1,likedByFollowing:[4,3]]]

This query is able to shuffle the values but shows all of the 'id's, now I want to select only the first 'id'. Using .next() instead of .fold() causes exception java.util.NoSuchElementException Is it possible to choose randomly without having to evaluate all the traversals first and then shuffling them?

Desired Output:

[post1:[likedBySelf:0,likedByFollowing:[]],post2:[likedBySelf:1,likedByFollowing:[3]]]

Or

[post1:[likedBySelf:0,likedByFollowing:[]],post2:[likedBySelf:1,likedByFollowing:[4]]]
Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You're pretty close to your answer:

gremlin> g = TinkerGraph.open().traversal()
==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
gremlin> g.addV('user').property('id',1).as('1').
......1>   addV('user').property('id',2).as('2').
......2>   addV('user').property('id',3).as('3').
......3>   addV('user').property('id',4).as('4').
......4>   addV('post').property('postId','post1').as('p1').
......5>   addV('post').property('postId','post2').as('p2').
......6>   addE('follow').from('1').to('2').
......7>   addE('follow').from('1').to('3').
......8>   addE('follow').from('1').to('4').
......9>   addE('posted').from('2').to('p1').
.....10>   addE('posted').from('2').to('p2').
.....11>   addE('liked').from('1').to('p2').
.....12>   addE('liked').from('3').to('p2').
.....13>   addE('liked').from('4').to('p2').iterate()
gremlin> g.V().has('id',1).as('me').
......1>   out('follow').
......2>   aggregate('followers').
......3>   out('posted').
......4>   group().
......5>     by('postId').
......6>     by(project('likedBySelf','likedByFollowing').
......7>          by(__.in('liked').where(eq('me')).count()).
......8>          by(__.in('liked').where(within('followers')).order().by('id',shuffle).values('id').limit(1).fold()))
==>[post2:[likedBySelf:1,likedByFollowing:[3]],post1:[likedBySelf:0,likedByFollowing:[]]]

I pretty much just added limit(1) so that only the first item after shuffle is selected. It took a few executions but I was able to see both of the outputs you were looking for with this method. As I suggested on your other question, you might also use sample(1):

gremlin> g.V().has('id',1).as('me').
......1>   out('follow').
......2>   aggregate('followers').
......3>   out('posted').
......4>   group().
......5>     by('postId').
......6>     by(project('likedBySelf','likedByFollowing').
......7>          by(__.in('liked').where(eq('me')).count()).
......8>          by(__.in('liked').where(within('followers')).sample(1).values('id').fold()))
==>[post2:[likedBySelf:1,likedByFollowing:[3]],post1:[likedBySelf:0,likedByFollowing:[]]]
gremlin> g.V().has('id',1).as('me').
......1>   out('follow').
......2>   aggregate('followers').
......3>   out('posted').
......4>   group().
......5>     by('postId').
......6>     by(project('likedBySelf','likedByFollowing').
......7>          by(__.in('liked').where(eq('me')).count()).
......8>          by(__.in('liked').where(within('followers')).sample(1).values('id').fold()))
==>[post2:[likedBySelf:1,likedByFollowing:[4]],post1:[likedBySelf:0,likedByFollowing:[]]]

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...