在 Cypher/Neo4j 中表达多对多关系
Expressing many-one-many relationships in Cypher/Neo4j
我正在尝试在 Cypher 中创建以下内容(所有名称都是虚构的,这是一个示例用例,而不是实际数据):
程序:
(po0:Program {name: "xxx"}),
(po1:Program {name: "yyy"}),
(po3:Program {name: "zzz"}),
好处:
(b0:Benefit {name: "happy world"}),
提供商
(pr0:Provider {name: "aaa"}),
(pr1:Provider {name: "bbb"}),
(pr3:Provider {name: "ccc"}),
我该如何表达每个计划都带来好处的想法 b0
,但该好处由不同的提供者提供,具体取决于计划。例如,计划 po0
提供由 pr0
提供的福利 b0
。计划 pr1
也提供好处 b0
,但是,由 pr1
提供。
如果我这样连接:
(po0)-[:GIVES]->(b0)-[:PROVIDED_BY]->(pr0),
(po1)-[:GIVES]->(b0)-[:PROVIDED_BY]->(pr1),
(po2)-[:GIVES]->(b0)-[:PROVIDED_BY]->(pr2),
然后我松开哪个程序使用哪个提供者之间的关系b0
。
连接它的正确方法是什么?
我能想到的最好的是:
(po0)-[:GIVES {provided_by: "xxx"}]->(b0),
(po1)-[:GIVES {provided_by: "yyy"}]->(b0),
(po2)-[:GIVES {provided_by: "zzz"}]->(b0),
但这对我来说似乎很奇怪,从那时起我就失去了对 Provider 节点的直接引用,导致不得不为它们做一个额外的查询。
[更新]
假设您添加了另一个节点标签 Service
,它表示特定的 Provider/Benefit
对。例如,如果您定义:
服务:
(s0:Service {name: "a"}),
(s1:Service {name: "b"}),
(s2:Service {name: "c"}),
...
... 那么您可以指示 Provider
提供具有 Benefit
的 Service
,如下所示。请注意,多个 Provider
可以提供相同的 Benefit
,反之亦然:
(pr0)-[:PROVIDES]-(s0)-[:HAS]->(b0),
(pr0)-[:PROVIDES]-(s1)-[:HAS]->(b1),
(pr1)-[:PROVIDES]-(s2)-[:HAS]->(b2),
(pr2)-[:PROVIDES]-(s3)-[:HAS]->(b2),
...
最后,您只需指出每个 Program
使用的 Service
。请注意,多个 Program
可以使用相同的 Service
(po0)-[:USES]->(s0),
(po0)-[:USES]->(s1),
(po1)-[:USES]->(s1),
(po2)-[:USES]->(s1),
...
我认为您需要的是完成三角形,并且 link 将程序返回给提供商。即
(po0)-[:GIVES]->(b0)-[:PROVIDED_BY]->(pr0)-[:RUN_BY]->(po0),
(po1)-[:GIVES]->(b0)-[:PROVIDED_BY]->(pr1)-[:RUN_BY]->(po1),
(po2)-[:GIVES]->(b0)-[:PROVIDED_BY]->(pr2)-[:RUN_BY]->(po2),
我正在尝试在 Cypher 中创建以下内容(所有名称都是虚构的,这是一个示例用例,而不是实际数据):
程序:
(po0:Program {name: "xxx"}),
(po1:Program {name: "yyy"}),
(po3:Program {name: "zzz"}),
好处:
(b0:Benefit {name: "happy world"}),
提供商
(pr0:Provider {name: "aaa"}),
(pr1:Provider {name: "bbb"}),
(pr3:Provider {name: "ccc"}),
我该如何表达每个计划都带来好处的想法 b0
,但该好处由不同的提供者提供,具体取决于计划。例如,计划 po0
提供由 pr0
提供的福利 b0
。计划 pr1
也提供好处 b0
,但是,由 pr1
提供。
如果我这样连接:
(po0)-[:GIVES]->(b0)-[:PROVIDED_BY]->(pr0),
(po1)-[:GIVES]->(b0)-[:PROVIDED_BY]->(pr1),
(po2)-[:GIVES]->(b0)-[:PROVIDED_BY]->(pr2),
然后我松开哪个程序使用哪个提供者之间的关系b0
。
连接它的正确方法是什么?
我能想到的最好的是:
(po0)-[:GIVES {provided_by: "xxx"}]->(b0),
(po1)-[:GIVES {provided_by: "yyy"}]->(b0),
(po2)-[:GIVES {provided_by: "zzz"}]->(b0),
但这对我来说似乎很奇怪,从那时起我就失去了对 Provider 节点的直接引用,导致不得不为它们做一个额外的查询。
[更新]
假设您添加了另一个节点标签 Service
,它表示特定的 Provider/Benefit
对。例如,如果您定义:
服务:
(s0:Service {name: "a"}),
(s1:Service {name: "b"}),
(s2:Service {name: "c"}),
...
... 那么您可以指示 Provider
提供具有 Benefit
的 Service
,如下所示。请注意,多个 Provider
可以提供相同的 Benefit
,反之亦然:
(pr0)-[:PROVIDES]-(s0)-[:HAS]->(b0),
(pr0)-[:PROVIDES]-(s1)-[:HAS]->(b1),
(pr1)-[:PROVIDES]-(s2)-[:HAS]->(b2),
(pr2)-[:PROVIDES]-(s3)-[:HAS]->(b2),
...
最后,您只需指出每个 Program
使用的 Service
。请注意,多个 Program
可以使用相同的 Service
(po0)-[:USES]->(s0),
(po0)-[:USES]->(s1),
(po1)-[:USES]->(s1),
(po2)-[:USES]->(s1),
...
我认为您需要的是完成三角形,并且 link 将程序返回给提供商。即
(po0)-[:GIVES]->(b0)-[:PROVIDED_BY]->(pr0)-[:RUN_BY]->(po0),
(po1)-[:GIVES]->(b0)-[:PROVIDED_BY]->(pr1)-[:RUN_BY]->(po1),
(po2)-[:GIVES]->(b0)-[:PROVIDED_BY]->(pr2)-[:RUN_BY]->(po2),