我想检索所有的顶点,并为每个顶点计算指向它的“喜欢”边的数量。如何编写子查询?
如何在Gremlin中编写这种查询?
在SQL它可能是这样的....
SELECT *, (SELECT Count(*) FROM tbl_like l WHERE l.id = b.id) AS LikeCount
FROM tbl_blah b
我想检索所有的顶点,并为每个顶点计算指向它的“喜欢”边的数量。如何编写子查询?
如何在Gremlin中编写这种查询?
在SQL它可能是这样的....
SELECT *, (SELECT Count(*) FROM tbl_like l WHERE l.id = b.id) AS LikeCount
FROM tbl_blah b
无需副作用...
g.V().transform{[it, it.in('likes').count()]}
例如使用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家伙可以详细说明关闭的确切用法。
我会考虑:
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提供的解决方案是更好的方法。你甚至可以从两种解决方案中挑选一些,最终找到你想要的东西。
最后我明白了'cap'。从doc:“cap'发出前一步的值(这里是来自'groupBy'的映射),而不是流过它的值(这里流过'groupBy'的边)”!谢谢!但是,因此'cap'的行为就像'gather',因为它收集所有对象直到'cap'步骤,对吗? – Faber 2014-11-04 14:25:46
我不确定我会走那么远。 'cap'只是提取上一步的副作用,而'gather'则处理管道中的对象,将流水线中的所有项目都抓到列表中。一个人使用管道对象,一个人抓住副作用......这是一个重要的区别。 – 2014-11-04 14:57:46
酷我就给你一展身手。 – 2014-11-04 12:59:23
你说得对,'b'是从闭包返回的前一个值。这样你就可以在通过'groupCount'的每个物品上增加'b'。在这种情况下,这是没有必要的,因为边数是你想要的。 – 2014-11-04 14:03:58
地图声明的文档在哪里?我在这里看不到它...http://gremlindocs.com/ – 2014-11-06 15:22:45