将实体与 Neo4j 中的适当关系相关联?
Relating an entity to a relationship proper in Neo4j?
我正在尝试使用 Neo4j 来模拟项目、员工和项目角色之间的关系。每个项目都有一个名为 "project manager" 的角色和一个名为 "director" 的角色。我试图在数据模型中完成的是能够说 "for project A, the director is staff X." 就我的目的而言,重要的是 "project"、"staff" 和 "role" 都是实体(而不是属性)。这在 Neo4j 中可能吗?简而言之,Neo4j 中是否可能存在关联实体?在 MySQL 中,这将用具有唯一 ID 列和三个外键列的联结 table 表示,一个分别用于项目、人员和角色,这将使我能够识别它们之间的关系实体作为实体本身。想法?
从概念上讲,Neo4j 图是基于两种主要类型构建的 - 节点和关系。节点可以与关系连接。但是,节点和关系都可以具有属性。
要连接Project
和Staff
节点,可以使用以下Cypher语句:
CREATE (p:Project {name:"Project X"})-[:IS_DIRECTOR]->(director:Staff {firstName:"Jane"})
这将创建两个节点。项目节点有一个 Label
类型 Project
,职员节点有一个 Label
类型 Staff
。在这些节点之间存在 IS_DIRECTOR
类型的关系,表明 Jane 是项目的主管。请注意,关系始终是定向的。
因此,要找到 all 项目的 all 位主管,可以使用以下方法:
MATCH (p:Project)-[:IS_DIRECTOR]->(director:Staff) RETURN director
另一种方法是将属性添加到更一般关系类型:
create (p:Project {name:"Project X"})<-[:MEMBER_OF {role:"Director"}]-(director:Staff {firstName:"Jane"})
这显示了如何向关系添加属性。请注意,第二个示例的关系方向已更改。
要使用基于 属性 的关系查找所有董事,可以使用以下方法:
MATCH (p:Project)<-[:MEMBER_OF {role:"Director"}]-(directors:Staff) RETURN directors
要检索所有角色类型(例如导演),可以使用以下内容:
MATCH
(p:Project)-[r]->(s:Staff)
RETURN
r, // The actual relationship
type(r), // The relationship type e.g. IS_DIRECTOR
r.role // If properties are available they can be accessed like this
并且,要获得唯一的角色名称列表,可以使用 COLLECT
和 DISTINCT
:
MATCH
(p:Project)-[r]->(s:Staff)
RETURN
COLLECT(DISTINCT type(r)) // Distinct types
或者,对于关系的属性:
MATCH
(p:Project)-[r]->(s:Staff)
RETURN
COLLECT(DISTINCT r.role) // The "role" property if that is used
COLLECT
returns 列表结果和 DISTINCT
关键字确保列表中没有重复项。
@wassgren 的回答很可靠,值得考虑。
我将提供另一种选择。也就是说,你可以“Reify”表示关系。具体化有点像你把关系变成一个节点。您正在采用抽象关联(员工与项目之间的关系)并将其转变为具体实体(角色)所有其他答案选项基本上涉及两个节点 Project
和 Staff
,随着它们之间关系的变化。这些方法不具体化角色,而是将其存储为关系的 属性 或标签。
(director:Staff {name: "Joe"})-[:plays]->(r:Role {label:"Director"})-[:member_of]->(p:Project { name: "Project X"});
所以...人们不会直接为项目做出贡献,角色会。人们扮演角色。这具有直观意义。
这种方法的优点是您可以将 "Role" 视为第一个 class 公民,并声明关于它的关系和属性。如果您不将 "Role" 拆分到一个单独的节点中,您将无法将关系挂在该节点之外。此外,如果您向伪装成角色的关系添加额外的属性,您可能最终会混淆 属性 何时适用于该角色,以及何时适用于员工与项目之间的关联.
想知道项目中有哪些人?那只是:
MATCH (p:Project {label: "Project X"})<-[:member_of]-(r:Role)<-[:plays]-(s:Staff)
RETURN s;
所以我认为我的建议从长远来看更灵活,但对您来说也可能有点矫枉过正。
考虑一个假设的未来需求:我们希望将角色与技术级别或工作类别相关联。 IE。项目经理应该始终是副总裁或更高级别(愚蠢的例子)。如果你的角色是一段关系,你就不能那样做。如果你的角色是一个合适的节点,你可以。
我正在尝试使用 Neo4j 来模拟项目、员工和项目角色之间的关系。每个项目都有一个名为 "project manager" 的角色和一个名为 "director" 的角色。我试图在数据模型中完成的是能够说 "for project A, the director is staff X." 就我的目的而言,重要的是 "project"、"staff" 和 "role" 都是实体(而不是属性)。这在 Neo4j 中可能吗?简而言之,Neo4j 中是否可能存在关联实体?在 MySQL 中,这将用具有唯一 ID 列和三个外键列的联结 table 表示,一个分别用于项目、人员和角色,这将使我能够识别它们之间的关系实体作为实体本身。想法?
从概念上讲,Neo4j 图是基于两种主要类型构建的 - 节点和关系。节点可以与关系连接。但是,节点和关系都可以具有属性。
要连接Project
和Staff
节点,可以使用以下Cypher语句:
CREATE (p:Project {name:"Project X"})-[:IS_DIRECTOR]->(director:Staff {firstName:"Jane"})
这将创建两个节点。项目节点有一个 Label
类型 Project
,职员节点有一个 Label
类型 Staff
。在这些节点之间存在 IS_DIRECTOR
类型的关系,表明 Jane 是项目的主管。请注意,关系始终是定向的。
因此,要找到 all 项目的 all 位主管,可以使用以下方法:
MATCH (p:Project)-[:IS_DIRECTOR]->(director:Staff) RETURN director
另一种方法是将属性添加到更一般关系类型:
create (p:Project {name:"Project X"})<-[:MEMBER_OF {role:"Director"}]-(director:Staff {firstName:"Jane"})
这显示了如何向关系添加属性。请注意,第二个示例的关系方向已更改。
要使用基于 属性 的关系查找所有董事,可以使用以下方法:
MATCH (p:Project)<-[:MEMBER_OF {role:"Director"}]-(directors:Staff) RETURN directors
要检索所有角色类型(例如导演),可以使用以下内容:
MATCH
(p:Project)-[r]->(s:Staff)
RETURN
r, // The actual relationship
type(r), // The relationship type e.g. IS_DIRECTOR
r.role // If properties are available they can be accessed like this
并且,要获得唯一的角色名称列表,可以使用 COLLECT
和 DISTINCT
:
MATCH
(p:Project)-[r]->(s:Staff)
RETURN
COLLECT(DISTINCT type(r)) // Distinct types
或者,对于关系的属性:
MATCH
(p:Project)-[r]->(s:Staff)
RETURN
COLLECT(DISTINCT r.role) // The "role" property if that is used
COLLECT
returns 列表结果和 DISTINCT
关键字确保列表中没有重复项。
@wassgren 的回答很可靠,值得考虑。
我将提供另一种选择。也就是说,你可以“Reify”表示关系。具体化有点像你把关系变成一个节点。您正在采用抽象关联(员工与项目之间的关系)并将其转变为具体实体(角色)所有其他答案选项基本上涉及两个节点 Project
和 Staff
,随着它们之间关系的变化。这些方法不具体化角色,而是将其存储为关系的 属性 或标签。
(director:Staff {name: "Joe"})-[:plays]->(r:Role {label:"Director"})-[:member_of]->(p:Project { name: "Project X"});
所以...人们不会直接为项目做出贡献,角色会。人们扮演角色。这具有直观意义。
这种方法的优点是您可以将 "Role" 视为第一个 class 公民,并声明关于它的关系和属性。如果您不将 "Role" 拆分到一个单独的节点中,您将无法将关系挂在该节点之外。此外,如果您向伪装成角色的关系添加额外的属性,您可能最终会混淆 属性 何时适用于该角色,以及何时适用于员工与项目之间的关联.
想知道项目中有哪些人?那只是:
MATCH (p:Project {label: "Project X"})<-[:member_of]-(r:Role)<-[:plays]-(s:Staff)
RETURN s;
所以我认为我的建议从长远来看更灵活,但对您来说也可能有点矫枉过正。
考虑一个假设的未来需求:我们希望将角色与技术级别或工作类别相关联。 IE。项目经理应该始终是副总裁或更高级别(愚蠢的例子)。如果你的角色是一段关系,你就不能那样做。如果你的角色是一个合适的节点,你可以。