处理路径中多个中间节点的最佳方法?

时间:2014-05-27 15:06:53

标签: graph-databases arangodb

基本上我有以下情况:

vertex --- vertex* --- vertex

然而,顶点*在路径中此点处可能具有可变数量的顶点,从而导致

vertex --- vertex1 --- vertex
vertex --- vertex2 --- vertex
vertex --- vertexN --- vertex

在我遍历这个顶点之前,我不知道N会是什么。当我第一次遍历此节点时,任意函数将能够确定此顶点在路径中此点的实例数。

我只是将N记录为属性,还是创建额外的N个具有递增值的中间顶点的路径?

一个真实的例子是,一个文件目录,文件夹数量未知(直到你打开父目录),每个文件夹包含一个文件,你需要遍历每个文件路径。

更新

这就是我的期望:

(第一次遍历,遇到具有特殊属性的顶点*)

A --- X* --- B 

生成相同X顶点的附加实例,连接到父A和子B。

A --- X1 --- B
 \--- X2 --/
  \-- X3 -/

   A --- X1 --- B
   A --- X2 --- B
   A --- X3 --- B

所以现在遍历将发生像

A, X1, B
A, X2, B
A, X3, B

X个顶点实例彼此完全相同,只有它们有一个索引整数。实例数由第一次初始遍历(A, X*, B)确定。 X *可能会生成3或50或100个其他实例。

对于存储,我的意思是将此索引值存储在X *并每次递增它,直到达到最大整数N。所以对于上面的例子,它的起始索引为1,最大值为3.这将绕过在中间插入额外顶点并将其连接到A和B的需要。但是,我不确定是否这对我的情况来说是最好的,我需要遍历每条生成的路径。

2 个答案:

答案 0 :(得分:2)

我有点困惑你实际上在寻找什么;)

首先,您可以进一步详细说明您的用例吗? 您在搜索两个顶点AB之间的所有顶点列表吗?

A --- vertex1 --- B
A --- vertex2 --- B
A --- vertexN --- B

或者您是否正在搜索特定深度A中可以到达的所有顶点(例如:2):

A --- vertex1 --- B
A --- vertex2 --- C
A --- vertexN --- D

其次,您是否正在寻找一种解决方案如何以最佳方式存储它? 或者你已经存储它并正在寻找一种如何查询它的方法? 如果你想查询它,你期望什么结果?路径数量? 或者是中间顶点的列表?

我认为我们可以解决上述所有问题;)

答案 1 :(得分:2)

所以我觉得现在我得到了你的用例。

你说得对,你基本上要选择:

  1. 替换顶点" x *"通过其他顶点:
    • 首先,我会执行一个简单的查询,搜索具有特殊属性的所有顶点(我不会在此步骤中使用遍历,但此特殊属性的索引应该更快)
    • 其次我会在事务中用相应数量的实顶点替换所有它们(如果你想再次执行这个查询,请记得删除" x *"顶点)
    • 第三,您可以使用所有内置的遍历语句,因为图形显示了查询结构。
  2. 临:

    • 易于实施。
    • 数据完全符合您的预期,不需要解析属性,如果您的应用程序中有从A到B的5条路径,则数据库中存储了从A到B的5条路径。
    • 可以大量使用内置功能(ArangoDB希望所有边缘都默认在物理上)

    缺点:

    • 冗余数据(X1-Xn是彼此的副本)所以如果你在这里存储一些数据,你必须小心保持同步
    • 更高的内存消耗。
    • 图表中的更多路径=>更多遍历步骤
    • 比选项2更低效。

    选项2:仅存储一个中间顶点并使用特殊属性

    1. 只存储顶点X *
    2. 实现您自己的访问者,该访问者检查特殊属性(根据您的描述,如果路径上的最后一个顶点(X *)具有特殊属性,我认为您要检查顶点B)。如果是这样,您将(A X B)n次的值添加到结果中。
    3. 临:

      • 高性能
      • 无冗余

      缺点:

      • 你必须实现逻辑,用你的应用程序中的X1 - Xn替换X *
      • 您必须实施自己的访客
      • 您的域模型与数据库中的内容之间存在轻微的不匹配

      我会根据数据集的大小做出决定。 如果你有一个非常小的数据集,冗余/性能不是问题,我会选择更简单,更省力的选项1。 如果您有一个大型数据集并且需要高性能选项2,我猜想会更好。

      希望有所帮助;)