如何为这种情况编写Cypher查询?

时间:2016-11-29 05:09:40

标签: java neo4j cypher

我有一张如下图所示的图表。enter image description here

WAR可以发布多个SERVICE,也可以DEPENDSON多个SERVICE。

我的要求是获得给定WAR的依赖WAR。

我知道如何编写查询以获得第一层依赖。

MATCH (w:WAR)-[:PUBLISH]->(s:SERVICE)<-[:DEPENDSON]-(otherWar:WAR)

我的问题是如何获得给定WAR的多层依赖。

在这种情况下,在war1和war3之间,有两个PUBLISH / DEPENDSON关系。如何用变长关系描述这种关系?

2 个答案:

答案 0 :(得分:3)

[增订]

找出一场战争取决于另一场战争的方式

假设PUBLISHDEPENDSON关系始终从WAR节点开始并以SERVICE节点结束,我相信此查询将找到war3节点的所有路径{ {1}}(最终)取决于war1

MATCH p=(w:WAR {name:'war1'})-[:PUBLISH]->
  ()-[:PUBLISH|DEPENDSON*0..]-()
  <-[:DEPENDSON]-(otherWar:WAR {name:'war3'})
RETURN p;

使用@GaborSzarnyas提供的相同样本数据,上述查询会产生以下结果:

+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| p                                                                                                                                                                          |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| [Node[6]{name:"war1"},:PUBLISH[6] {},Node[9]{name:"s1"},:DEPENDSON[8] {},Node[7]{name:"war2"},:PUBLISH[10] {},Node[11]{name:"s3"},:DEPENDSON[11] {},Node[8]{name:"war3"}]  |
| [Node[6]{name:"war1"},:PUBLISH[7] {},Node[10]{name:"s2"},:DEPENDSON[9] {},Node[7]{name:"war2"},:PUBLISH[10] {},Node[11]{name:"s3"},:DEPENDSON[11] {},Node[8]{name:"war3"}] |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+

查找战争的依赖关系

此查询应查找依赖于WAR的所有不同war1个节点:

MATCH (w:WAR {name:'war1'})-[:PUBLISH]->()-[:PUBLISH|DEPENDSON*0..]-()<-[:DEPENDSON]-(otherWar:WAR)
RETURN DISTINCT otherWar;

结果是:

+----------------------+
| otherWar             |
+----------------------+
| Node[7]{name:"war2"} |
| Node[8]{name:"war3"} |
+----------------------+

答案 1 :(得分:2)

据我所知,没有办法在子图上创建可变长度路径,即你不能陈述像(){-[:PUBLISH]->(:SERVICE)<-[:DEPENDSON]-}*()这样的东西。

我使用以下代码复制了您的示例数据集:

CREATE
   (war1:WAR {name: 'war1'}),
   (war2:WAR {name: 'war2'}),
   (war3:WAR {name: 'war3'}),
   (s1:SERVICE {name: 's1'}),
   (s2:SERVICE {name: 's2'}),
   (s3:SERVICE {name: 's3'}),
   (war1)-[:PUBLISH]->(s1),
   (war1)-[:PUBLISH]->(s2),
   (war2)-[:DEPENDSON]->(s1),
   (war2)-[:DEPENDSON]->(s2),
   (war2)-[:PUBLISH]->(s3),
   (war3)-[:DEPENDSON]->(s3)

如果在您的用例中可以这样做,则在图表中插入其他边缘:

MATCH (w:WAR)-[:PUBLISH]->(s:SERVICE)<-[:DEPENDSON]-(otherWar:WAR)
MERGE (w)<-[:WAR_DEPENDS]-(otherWar)

并使用它们进行遍历:

MATCH (w1:WAR)-[:WAR_DEPENDS*]->(w2:WAR)
RETURN w1, w2

这给出了:

╒════════════╤════════════╕
│w1          │w2          │
╞════════════╪════════════╡
│{name: war1}│{name: war2}│
├────────────┼────────────┤
│{name: war1}│{name: war3}│
├────────────┼────────────┤
│{name: war2}│{name: war3}│
└────────────┴────────────┘

如果你不想坚持这个优势,那就是在一个查询中运行它并且提交事务:

MATCH (w:WAR)-[:PUBLISH]->(s:SERVICE)<-[:DEPENDSON]-(otherWar:WAR)
MERGE (w)<-[:WAR_DEPENDS]-(otherWar)
WITH otherWar AS w1
MATCH (w1)-[:WAR_DEPENDS*]->(w2:WAR)
RETURN DISTINCT w1, w2

这再次导致:

╒════════════╤════════════╕
│w1          │w2          │
╞════════════╪════════════╡
│{name: war2}│{name: war1}│
├────────────┼────────────┤
│{name: war3}│{name: war1}│
├────────────┼────────────┤
│{name: war3}│{name: war2}│
└────────────┴────────────┘