在gremlin中,“连接”图形的两个节点的正确方法是什么?

在gremlin中,“连接”图形的两个节点的正确方法是什么?,gremlin,Gremlin,假设我有一个下图 graph = TinkerGraph.open() g = graph.traversal() v1 = g.addV('CC').property('name','t1') v2 = g.addV('KK').property('name','t1') 我想找到所有与KK具有相同“名称”的CC。我可以写: g.V().hasLabel('CC').as('c').values('name').as('cn').V().hasLabel('KK').values('name

假设我有一个下图

graph = TinkerGraph.open()
g = graph.traversal()
v1 = g.addV('CC').property('name','t1')
v2 = g.addV('KK').property('name','t1')
我想找到所有与KK具有相同“名称”的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中的连接,但编写时性能似乎很差。从中,它们有一个连接两个节点的示例,如果两个节点之间有一条边连接。我想知道在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和KK的完整图形扫描以获得结果。很明显,在一个大的图上这是非常昂贵的

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

SQL风格的联接对于graph db引擎的使用非常糟糕。喜欢 Daniel建议应预先计算连接,并在 写时间/数据我开玩笑说时间

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

通常,在图形中预计算边要便宜得多 加载数据前分离引擎,而不是加载数据后分离引擎 进入图表。例外情况是确定边时 基于通过图形的多跳路径。对于该用例,需要一个图 dB是最好的