0

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

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


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

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

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

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


现在,使用传出边缘,我可以轻松找出 Nirmalya喜欢哪些网站。

但是,当我想知道还有谁喜欢Nirmalya 喜欢的东西(即 John)时,我倾向于认为我也应该创建从站点类型节点到人员类型节点的边(使用属性“isLikedBy”),所以路径是明显的,遍历是直观的。每个人和站点都必须在两个方向上连接,以便我可以从任一方向到达另一个以回答像这样的查询。


[Nirmalya] -- (喜欢) --> [StackOverFlow] -- (IsLikedBy) --> [John]


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

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

我会很高兴变得更聪明。

4

1 回答 1

1

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

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

于 2015-08-05T14:02:40.960 回答