2014-10-08 165 views
3

我刚刚开始使用Neo4j和图形数据库,并且想知道嵌套层次树是否是Neo4j的一个好用例。一个常见的例子是一组嵌套的评论。例如:如何在Neo4j中实现嵌套树?

- Article 
    - Comment 1 on Article 
    - Comment 2 on Comment 1 
    - Comment 3 on Comment 1 
     - Comment 4 on Comment 3 
    - Comment 5 on Article 

据我所知,文章和评论都是节点。每个评论都会有一个亲子关系。对文章(1和5)直接发表评论会很容易。但是如何检索整个集合?

请原谅使用外行条款。我认为这样做更好,然后试图在使每个人都感到困惑的同时使用适当的词语。

回答

5

那么,因为trees actually are graphs使用图形数据库来存储树似乎完全适合我。什么会表现最好取决于你的数据访问模式,但基本上树只是图的专业化。

是的,在你的情况下,“树中的元素”将是节点,“嵌套”将是关系。因此,您可以模拟您的示例:

CREATE (root:Article {label: "Article"}), 
     (c1:Comment {label: "Comment 1"}), 
     (c1a:Comment {label: "Comment 2 on comment 1"}), 
     (c1b:Comment {label: "Comment 3 on comment 1"}), 
     (c1b1:Comment {label: "Comment 4 on comment 3"}), 
     (c2:Comment {label: "Comment 5 on article"}), 
     (root)<-[:reply]-(c1), 
     (c1)<-[:reply]-(c1a), 
     (c1)<-[:reply]-(c1b), 
     (c1b)<-[:reply]-(c1b1), 
     (root)<-[:reply]-(c2); 

这只是创建一堆节点和关系,模仿您提供的结构。在这里,我选择总是使用:reply来连接东西。

现在,“让一切”只是意味着遍历所有我们创建的:reply关系:

MATCH p=(a:Article {label: "Article"})<-[:reply*1..]-(otherThing) 
WITH nodes(p) as nodes 
RETURN nodes[length(nodes)-2] as InResponseTo, 
     nodes[length(nodes)-1] as CommentOrReply; 

什么这个查询确实是穿越任何数量的:reply链接(从根“条”开始)。然后,它只查看该路径中的节点,并返回最后一个项目(CommentOrReply)以及响应(第二个最后一项)的内容。

结果看起来是这样的:

+-------------------------------------------------------------------------------------+ 
| InResponseTo        | CommentOrReply       | 
+-------------------------------------------------------------------------------------+ 
| Node[18]{label:"Article"}    | Node[19]{label:"Comment 1"}    | 
| Node[19]{label:"Comment 1"}    | Node[20]{label:"Comment 2 on comment 1"} | 
| Node[19]{label:"Comment 1"}    | Node[21]{label:"Comment 3 on comment 1"} | 
| Node[21]{label:"Comment 3 on comment 1"} | Node[22]{label:"Comment 4 on comment 3"} | 
| Node[18]{label:"Article"}    | Node[23]{label:"Comment 5 on article"} | 
+-------------------------------------------------------------------------------------+ 

所以这就是你如何遍历整个树。

编辑 - 为它的价值,“可变长度路径匹配”,这在上面的查询只是该位:<-[:reply*1..]-是我图形数据库前3名卖点之一。正是这些图形数据库变得非常简单,大多数其他替代方法(如关系数据库)都是一个非常痛苦的练习。所以如果你需要做这样的事情(就像这里,组装一棵树),我会声称这是一个图形数据库的争论,因为你在它的基本实力领域使用它。

+2

如果你想看到更多的树的用例,请查看:http://jexp.de/blog/2014/04/importing-forests-into-neo4j/和http://blog.bruggen .com/search?q =层次结构 – 2014-10-08 15:33:23

+0

非常感谢您的精彩答案!我正试图弄清楚如何从这个结果中检索嵌套散列,例如在JSON中。但这不是一个真正的数据库问题......总的来说,一切看起来都比你在使用MySQL时必须提出的嵌套集方法快得多。 – 2014-10-08 16:20:37

+0

是的;在mysql中,常见模式是只有一个表连接到自身的节点 - 检查3-4之间的深度会变得非常困难。 – FrobberOfBits 2014-10-08 17:39:51

0

如果嵌套树是完全有向图且没有周期(即有向非循环图= DAG),那么可以考虑关系数据库中的传递闭包方法。这些允许通过多个嵌套层次的非常快速的查询找到多个交叉点。他们有n平方问题,所以有很多行,但是用bigint索引查询运行速度很快。