Gremlin - 随机选择一项
Gremlin - Choose one item at random
将我视为 'user' 1. 查询的目的是获取我关注的人的帖子 'posted',并为每个帖子检查:
- 是否被我点赞
- 它是否被我关注的其他人点赞,如果是随机选择其中一个用户return
示例数据:
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()
查询:(如此处回答:)
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()))
输出:
[post1:[likedBySelf:0,likedByFollowing:[]],post2:[likedBySelf:1,likedByFollowing:[4,3]]]
此查询能够打乱值但显示所有 'id',现在我只想 select 第一个 'id'。使用 .next() 而不是 .fold() 会导致异常 java.util.NoSuchElementException
是否可以随机选择而不必先评估所有遍历然后将它们打乱?
期望的输出:
[post1:[likedBySelf:0,likedByFollowing:[]],post2:[likedBySelf:1,likedByFollowing:[3]]]
或
[post1:[likedBySelf:0,likedByFollowing:[]],post2:[likedBySelf:1,likedByFollowing:[4]]]
您非常接近您的答案:
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:[]]]
我几乎只是添加了 limit(1)
,以便仅选择 shuffle
之后的第一项。执行了几次,但我能够看到您使用此方法寻找的两个输出。正如我在您的其他问题上所建议的那样,您也可以使用 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:[]]]
将我视为 'user' 1. 查询的目的是获取我关注的人的帖子 'posted',并为每个帖子检查:
- 是否被我点赞
- 它是否被我关注的其他人点赞,如果是随机选择其中一个用户return
示例数据:
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()
查询:(如此处回答: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()))
输出:
[post1:[likedBySelf:0,likedByFollowing:[]],post2:[likedBySelf:1,likedByFollowing:[4,3]]]
此查询能够打乱值但显示所有 'id',现在我只想 select 第一个 'id'。使用 .next() 而不是 .fold() 会导致异常 java.util.NoSuchElementException 是否可以随机选择而不必先评估所有遍历然后将它们打乱?
期望的输出:
[post1:[likedBySelf:0,likedByFollowing:[]],post2:[likedBySelf:1,likedByFollowing:[3]]]
或
[post1:[likedBySelf:0,likedByFollowing:[]],post2:[likedBySelf:1,likedByFollowing:[4]]]
您非常接近您的答案:
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:[]]]
我几乎只是添加了 limit(1)
,以便仅选择 shuffle
之后的第一项。执行了几次,但我能够看到您使用此方法寻找的两个输出。正如我在您的其他问题上所建议的那样,您也可以使用 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:[]]]