嗯,因为实际上树是图形,所以使用图形数据库来存储树在我看来是完全合适的。最佳表现取决于您的数据访问模式,但基本上树只是图形的一种特化。
是的,在您的情况下,“树中的元素”将是节点,“嵌套”将是关系。因此,这是您可能会模拟您的示例的方法:
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
链接(从根节点"Article"开始)。然后它只查看该路径中的节点,并返回最后一项(
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..]-
,是图数据库的前三大卖点之一。正是由于此,图形数据库使得大多数其他选择(如关系型数据库)变得非常艰难。因此,如果您需要做这种事情(例如在此处组装整个树),我会认为这表明支持使用图形数据库,因为您正在使用其基本强项所在的领域。
WHERE NOT ()-->(a)
将根节点绑定到实际根节点即可。 - Tezra