图探索:选择使用传入边还是传出边会影响性能?

Graph exploration: does the choice to use incoming edges or outgoing edges affect performance?

一段时间以来,我一直在修补图形,我使用它们实现了 适当 服务器端堆栈的 objective 部分。我用过 Scala-Graph 和 Neo4J,我正在学习 Spark GraphX。在我实现的几乎所有应用程序中,模型都是 属性 图(节点 -> 边 -> 节点,具有属性)。

在设计图形(准确地说是 DAG)时,如果我发现两个节点之间存在很强的定向关系,我会设置从一个节点到另一个节点的边。这是显而易见和直观的。如果一个人 喜欢 一个站点,则 属性 'likes' 的边将他们连接起来。因此:


[Nirmalya] --(喜欢)--> [Whosebug]

[约翰] --(喜欢)--> [Whosebug]

[Ted] --(喜欢)--> [GoogleGroups]

[Nirmalya] -- (赞)--> [Neo4J]


现在,使用 出站 边,我可以轻松找出 Nirmalya 喜欢 的网站。

但是,当我想找出还有谁喜欢 Nirmalya 喜欢什么(即 John)时,我倾向于认为我应该从 Site-type 节点创建一个边缘对Person类型的Node也一样(with 属性 'isLikedBy'),这样路径明显,遍历直观。每个 Person 和 Site 都必须在两个方向上连接,这样我就可以从任何一个方向联系到另一个来回答像这样的查询。


[Nirmalya] --(点赞)--> [Whosebug] -- (IsLikedBy) --> [John]


但是从专家们举的很多例子来看,我看并不是这样规定的。相反,这是通过使用像 incoming 这样的运算符来实现的。换句话说,如果两个节点之间设置了一条边,我不需要明确设置边的两个方向(只需 'likes' 就足够了, 'isLikedBy' 是多余的)。邻接矩阵的实现也许使这成为可能,但我有点困惑,因为即使在 DAG 中该方向不明确,我也被允许导出一个相反的方向。

我的问题是我的理解差距在哪里? 'IsLikedBy' 方向是否理想情况下应该存在,但我们正在优化?或者,是否存在需要此类双向边缘的用例,我需要发现它们?我是否完全缺少理论基础?

我会很高兴变得更聪明。

我认为这取决于软件。我可以代表 Neo4j,但不能代表您提到的其他工具 ;)

在 Neo4j 中,关系被设计为可向前和向后遍历而无需性能成本。这既适用于 Java API 中的遍历,也适用于使用 Cypher。您可以同时查询指定方向 incoming/outgoing 以及查询关系而不关心方向,它也应该是相同的性能特征。