2014-11-04 108 views
0

我想检索所有的顶点,并为每个顶点计算指向它的“喜欢”边的数量。如何编写子查询?

如何在Gremlin中编写这种查询?

在SQL它可能是这样的....

SELECT *, (SELECT Count(*) FROM tbl_like l WHERE l.id = b.id) AS LikeCount 
FROM tbl_blah b 

回答

0

无需副作用...

g.V().transform{[it, it.in('likes').count()]} 
1

例如使用sideEffect把计数地图(m

m=[:];g.V.sideEffect{m[it]=it.inE.has('label','like').count()} 

其省略了顶点0喜欢一种替代方案:

m=[:];g.V.inE('like').groupCount(m){it.inV.next()} 

编辑

最后聪明的解决方案:

m=[:];g.V.groupCount(m){it}{it.a.inE('like').count()} 

该fi第一次关闭groupCount确定要在地图中更新的密钥,第二次将值关闭到密钥。好像it.a在第二个闭包中给出的当前输入值为groupCount(这里是一个顶点)和it.b这个输入对象在map中的前一个值。还没有真正找到解释这一点的文档,也许其中一个TinkerPop家伙可以详细说明关闭的确切用法。

+0

酷我就给你一展身手。 – 2014-11-04 12:59:23

+0

你说得对,'b'是从闭包返回的前一个值。这样你就可以在通过'groupCount'的每个物品上增加'b'。在这种情况下,这是没有必要的,因为边数是你想要的。 – 2014-11-04 14:03:58

+0

地图声明的文档在哪里?我在这里看不到它...http://gremlindocs.com/ – 2014-11-06 15:22:45

1

我会考虑:

m = g.E.has('label','like').groupBy{it.inV.next()}{1}{it.sum()}.cap.next() 

迭代每个“喜欢”边缘的inV所有边缘和过滤通过标签组,并添加一个1到结果的那Map。这很大程度上将你带到第二次到最后关闭groupBy。在这一点上,你将有一个Map喜欢:

[v1:[1,1,1] 
v2:[1,1]] 

这基本上是一个1顶点代表每个“喜欢”的边缘。回到上面的Gremlin,groupBy的最后一次关闭是在Map的值上发生的简化操作。在这种情况下,我们使用Groovy sum函数(尽管我认为size也可以在这里工作 - 但sum似乎更易于阅读)加起来的边数。最后,我们用cap从流水线中提取Map副作用,并用next把它变成var。

我想这里的缺点是,它不会产生没有“喜欢”边缘的顶点的结果。如果您需要,那么@Faber提供的解决方案是更好的方法。你甚至可以从两种解决方案中挑选一些,最终找到你想要的东西。

+0

最后我明白了'cap'。从doc:“cap'发出前一步的值(这里是来自'groupBy'的映射),而不是流过它的值(这里流过'groupBy'的边)”!谢谢!但是,因此'cap'的行为就像'gather',因为它收集所有对象直到'cap'步骤,对吗? – Faber 2014-11-04 14:25:46

+2

我不确定我会走那么远。 'cap'只是提取上一步的副作用,而'gather'则处理管道中的对象,将流水线中的所有项目都抓到列表中。一个人使用管道对象,一个人抓住副作用......这是一个重要的区别。 – 2014-11-04 14:57:46