在 gremlin "join"图的两个节点的正确方法是什么?



假设我有一个下面的图

graph = TinkerGraph.open()
g = graph.traversal()
v1 = g.addV('CC').property('name','t1')
v2 = g.addV('KK').property('name','t1')

我想找到所有具有与KK相同的'name'CC。我可以写:

g.V().hasLabel('CC').as('c').values('name').as('cn').V().hasLabel('KK').values('name').as('k').where('cn',eq('k')).select('c')

这模仿了SQL中的联接,但编写时性能似乎很差。从SQL2Gremlin中,他们有一个例子,如果两个节点之间有一条连接的边,就可以"连接"两个节点。我想知道在gremlin中是否有任何连接方法,即是否有连接两个节点的路径事先是未知的?换句话说,在gremlin中编写"join"的最佳方法是什么?我们不知道这两个节点是否直接连接或通过路径连接?

非常感谢!

你的直觉基本上是正确的。"连接"是两个顶点之间实现的关系(即边(。这通常是图形数据库中的增益。在SQL样式中对属性执行顶点到顶点连接通常对图形无效。

至于您的查询,为了更清楚起见,您可以将其重新写入此表单:

gremlin> g.V().hasLabel('CC').as('c').
......1>   V().hasLabel('KK').
......2>   where(eq('c')).
......3>     by('name').
......4>   select('c')
==>v[0]

然而,性能可能会保持不变,因为我认为目前没有任何图形系统会优化这种遍历。不会有索引使用,您将留下"CC"one_answers"KK"的完整图形扫描来获得结果。显然,在大型图形上,这是非常昂贵的。

在这里的Gremlin用户邮件列表中有一些关于这个主题的讨论,其中提出了一些不错的观点。值得注意的是,Josh Perryman写道(除其他优点外(:

SQL风格的联接是对图形数据库引擎的一种非常糟糕的使用。喜欢Daniel建议应该预先计算连接,并在写时间/数据我拿时间开玩笑。

这是出于需要和设计。边缘基本实现联接。图形数据库针对它们进行了优化,磁盘或缓存读取活动关系数据库针对联接(查询时间(进行了优化计算机操作。

在在加载数据之前分离引擎,而不是在加载数据之后这样做进入图表。例外情况是在确定边时基于通过图的多跳路径。对于该用例,图形dB是最好的。

最新更新