【问题标题】:Graph exploration: does the choice to use incoming edges or outgoing edges affect performance?图探索:选择使用传入边还是传出边会影响性能吗?
【发布时间】:2015-08-05 22:02:40
【问题描述】:

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

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


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

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

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

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


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

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


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


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

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

我会很高兴变得更聪明。

【问题讨论】:

    标签: graph graph-traversal property-graph


    【解决方案1】:

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

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

    【讨论】:

    • 谢谢@Brian。就我的理解而言,在基于 Neo4J 的 DAG 中,哪个 direction 是边缘指向并不重要。如果 NodeA pointsTo NodeB 和 NodeC,我可以使用相同的单向边(A 到 B 和 not B 到 A)找出 NodeB 和 NodeC。我了解 Neo4J 如何使这成为可能,但我很好奇:这不违反 DAG 的约束吗?即使 B 和 C 不 pointTo A,我也可以发现这种关系,只给出 A。这不是有点违反直觉吗?这是我的实际问题。
    • 也许思考的方式是 Neo4j 中的关系是与节点分开存储的对象/实体本身。它们有一个开始节点和一个结束节点,因此您始终可以使用指向任一节点的指针。 Neo4j 中的方向性只是用户选择伴随关系类型的建模概念(也就是说,如果类型是“WROTE_BOOK”,我们希望方向从Person 变为Book
    • 抱歉,回复晚了! @Brian,感谢您的澄清。是的,我了解存储关系的方式使这成为可能。在实现方面,Neo4J 对于关系的方向严格。在某种程度上,当人们看到 Neo4J 所允许的(并且,我同意它是有益的)时,DAG 并不是它真正理解的那样。
    猜你喜欢
    • 2016-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多