考虑上面的图表。我想要一个gremlin查询,它返回所有在它们之间有多条边的节点,如图所示。
此图表是使用neo4j cypher查询获得的: MATCH(d:dest) - [r] - (n:cust) 与d,n,count(r)一样受欢迎 返回d,n 按受欢迎的desc限制5
例如: 在 RITUPRAKA ...和亚洲之间有8个多边,因此查询返回了2个节点以及边缘,类似于其他节点。
注意:图表中的其他节点之间只有一条边,这些节点不会被返回。
我想在 gremlin 中做同样的事情。
我使用了以下查询 GV()。如( '出')。出来()。如( '在')。( '在' '出',)中进行选择。groupCount()。展开()。过滤器(选择(值)。是( GT(1)))。选择(键)
正在显示 out:v [1234],in:v [3456] .....
但不是显示我希望显示节点值的节点的ID 喜欢:ICIC1234,in:HDFC234
我将查询修改为 g.V()。值( “名称”)。如( '出')。出来()。如( '在')。值( “名称”)。选择( '在' '出')。 groupCount()。展开()。过滤器(选择(值)。是(GT(1)))。选择(键)
但它显示错误,如classcastException,要遍历的每个顶点都使用索引进行快速迭代
答案 0 :(得分:4)
您的图表似乎并不表示双向边缘是可能的,因此我会记住这个假设。这是一个简单的示例图表 - 请考虑在未来的问题中加入一个,因为它比阅读您的问题的人更容易理解图片和文字描述,并开始编写Gremlin遍历来帮助您:
g.addV().property(id,'a').as('a').
addV().property(id,'b').as('b').
addV().property(id,'c').as('c').
addE('knows').from('a').to('b').
addE('knows').from('a').to('b').
addE('knows').from('a').to('c').iterate()
所以你可以看到顶点" a"有两个外边缘到" b"和#34; c"的一个外向边缘,因此我们应该得到" a b"顶点对。获得这个的一种方法是:
gremlin> g.V().as('out').out().as('in').
......1> select('out','in').
......2> groupCount().
......3> unfold().
......4> filter(select(values).is(gt(1))).
......5> select(keys)
==>[out:v[a],in:v[b]]
上述遍历使用groupCount()
来计算" out"的次数。和" in"标记的顶点显示(即它们之间的边数)。它使用unfold()
遍历Map
<Vertex Pairs,Count>
(或更多字面<List<Vertex>,Long>
)并过滤掉计数大于1的那些(即多边)。最后的select(keys)
会丢掉&#34;计数&#34;因为它不再需要(即我们只需要为结果保存顶点对的键)。
或许另一种方法是采用这种方法:
gremlin> g.V().filter(outE()).
......1> project('out','in').
......2> by().
......3> by(out().
......4> groupCount().
......5> unfold().
......6> filter(select(values).is(gt(1))).
......7> select(keys)).
......8> select(values)
==>[v[a],v[b]]
此方法project()
放弃了整个图表中较大groupCount()
的较大内存要求,有利于为符合条件的个人Map
构建较小的Vertex
用于by()
末尾的垃圾收集(或基本上每个处理的初始顶点)。
答案 1 :(得分:0)
我的建议与Stephen的相似,但也包括边缘或整个路径(我猜Cypher查询也返回了边缘)。
g.V().as("dest").outE().inV().as("cust").
group().by(select("dest","cust")).by(path().fold()).
unfold().filter(select(values).count(local).is(gt(1))).
select(values).unfold()