在图数据库中排序关系(neo4j)

时间:2016-01-09 09:10:42

标签: neo4j graph-databases

我正在发现图形数据库逻辑,阅读O'Reilly的图形数据库手册。我很热情,但还是有一些问题。

我的第一个问题是关系。假设我想模仿文本和讨论它们的手稿之间的关系。

所以我将有两种类型的节点(两个标签):

  • 手稿
  • 文本

一份手稿可以包含多个文本,一个文本可以包含在多个手稿中。所以我会有类似(ms:MS {identification}) -[:CONTAINS]->(txt:TXT {identification})的内容。

但问题是如何在一个手稿中存储和请求文本的顺序。我应该在CONTAINS关系中添加“订单”属性吗?申请表现如何:

  • 获取特定稿件中的文本的订单列表
  • 知道文本在之前的文稿和其他文本,以及文本在同一个其他文本之后。例如,我想知道文本“A”在“B”之前的所有手稿以及文本“B”在文本“A”之前的所有手稿。

2 个答案:

答案 0 :(得分:2)

快速回答,是的,边缘CONTAINS的订单属性,以及性能,非常快。

  

我应该在CONTAINS关系中添加“order”属性吗?

是的,向CONTAINS边添加订单属性是有意义的。

为什么有意义?让我们想象其他地方在手稿中存储文本的顺序:

a)在手稿中存储文本的顺序:为了能够做到这一点,你需要保留[文本,顺序]的列表,以便知道什么文本在什么位置。

b)在文本中存储文本的顺序:在这种情况下,在文本节点中,你需要保留[手稿,顺序]列表,以便知道文本在什么位置的文本对于每个不同的手稿,文本出现在。

虽然这两个是有效的建模选项,但当您尝试使用这两个不同的选项执行查询时,在插入,编辑,删除或查询节点时,您自己就更难了。

  

请求中的表现如何:

在回答具体方案之前,只需提醒一下:访问节点并在Neo4j中横穿关系,两者的成本都为O(1)

修改:有关此其他question from SO

的效果的其他信息
  

获取特定稿件中的文本的订单列表

因此对于带有n文本的手稿,检索所有文本的操作的总成本大致为O(n),并且将它们全部排序,应该可以承担O(n*log n),因此将取决于每份手稿的文本数量。

更新:如果您想要将评估中所要求的成本与关系数据库进行比较,那么,假设一个类似的模型,有3个表,一个用于手稿,一个用于文本,一个对于与订单的关系,遵循多对多属性方法。你将最终扫描整个关系表,这将意味着成本会更高,因为它将取决于所有手稿和文本之间的所有现有关系,而不仅仅是一个子集。

  

知道文本在之前和其他文本的哪些手稿中,以及它在同一个其他文本之后。例如,我想知道文本“A”在“B”之前的所有手稿以及文本“B”在文本“A”之前的所有手稿。

了解文本所处的稿件,就像横穿所有传入的CONTAINS关系一样简单,这意味着此操作为O(n)n文本显示的稿件数量为n in。

但是对于文本A出现在文本B之前的手稿,这有点复杂,而且更昂贵,我会尝试将其分解:

鉴于m是文本A出现的手稿数量,O(n+m)是文本B出现的手稿数量。

  1. 首先需要找到文本A所在的所有手稿,以及文本B所在的所有手稿。此操作的成本为O(n+m),仍为线性< / p>

  2. 然后需要过滤这些列表,找到两个列表中出现的稿件。这再次花费CONTAINS

  3. 最后再次过滤传出CONTAINS边缘的清单,具有订单属性,其中文本A的CONTAINS顺序小于O(k)的订单属性文本B.费用大致为k,其中Toad是手稿列表的大小,即步骤2的结果。

  4. 对于这种情况,当使用关系数据库时,将需要扫描整个关系表,这将不太高效,因为它将取决于表上的行数,而不仅仅是子集。

答案 1 :(得分:1)

两者都是明智的。

如果在文本之间创建:NEXT关系,则更容易维护。

对于订单属性,如果删除或插入一个文本,则必须更新所有这些属性。

添加新文本时,只需将它们附加到最后一个文本,其中包含:NEXT关系。

然后您可以按以下顺序获取稿件的所有文本:

MATCH (m:MS {id:"..."})-[:CONTAINS]->()-[:NEXT*0..]->(text:TXT)
RETURN m, collect(distinct text);