假设我有一个下面的图
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是最好的。