Neo4J - 存储关系与节点

Raz*_*ead 4 neo4j relationships graph-databases

我想知道将数据存储到关系或节点中是否有任何优点或缺点.

例如,如果我要将与讨论相关的注释存储到数据库中,是否应将注释数据存储在"注释"关系或通过单独关系与讨论相关的"注释"节点中.

cyb*_*sam 10

正确的数据模型取决于您需要进行的查询类型.您应该弄清楚您的查询是什么,然后确定满足以下条件的数据模型:

  1. 它允许您回答所有查询,
  2. 它允许您的查询足够快地完成,
  3. 它最小化了所需的数据库存储.

在讨论评论的情况下,您可能希望查询按时间顺序排列的讨论主题.因此,您不仅需要存储注释的时间,还需要存储注释之间的关系(因为讨论可以生成不共享相同优先注释的不相交线程).

我们来试试一个简单的测试用例吧.假设有两个不相交的线程由同一个初始注释产生(我们称之为c1):[c1,c3]和[c1,c2,c4].并且假设,在这个简单的测试用例中,我们只对查询与主题相关的所有评论线程感兴趣.

如果注释属性存储在节点中,则数据可能如下所示:

(u1:User {name: "A"})-[:MADE]->(c1:Comment {time:0, text: "Fee"})-[:ABOUT]->(s1:Subject {title: "Jack"})
(u2:User {name: "B"})-[:MADE]->(c2:Comment {time:1, text: "Fie"})-[:ABOUT]->(c1)
(u3:User {name: "C"})-[:MADE]->(c3:Comment {time:3, text: "Foe"})-[:ABOUT]->(c1)
(u4:User {name: "D"})-[:MADE]->(c4:Comment {time:9, text: "Fum"})-[:ABOUT]->(c2)
Run Code Online (Sandbox Code Playgroud)

如果您将注释属性存储在关系中,您可能会尝试类似下面的内容,但是有一个大的FLAW.关系无法直接指向另一种关系(正如我们在第2至4行中所做的那样).由于此模型在neo4j中不合法,因此无法满足上述任何条件.

(u1:User {name: "A"})-[c1:COMMENTED_ABOUT {time:0, text: "Fee"}]->(s1:Subject {title: "Jack"})
(u2:User {name: "B"})-[c2:COMMENTED_ABOUT {time:1, text: "Fie"}]->(c1)
(u3:User {name: "C"})-[c3:COMMENTED_ABOUT {time:3, text: "Foe"}]->(c1)
(u4:User {name: "D"})-[c4:COMMENTED_ABOUT {time:9, text: "Fum"}]->(c2)
Run Code Online (Sandbox Code Playgroud)

因此,在我们的简单测试用例中,看起来将属性存储在节点中是唯一的选择.

这是一个获取不相交的线程路径的查询,包括发表每条评论的用户( WHERE子句过滤掉部分线程):

MATCH p=(s:Subject)<-[:ABOUT*]-(c:Comment)<-[m:MADE]-(u:User)
WHERE NOT (c)<-[:ABOUT]-()
RETURN p
Run Code Online (Sandbox Code Playgroud)