2016-11-29 75 views
3

我有一个如下图所示的图表。 enter image description here如何为这种情况编写Cypher查询?

WAR可以发布多个服务,也可以发布多个服务。

我的要求是获得给定WAR的相关WAR。

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

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

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

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

回答

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}│ 
└────────────┴────────────┘ 
+1

我认为这是一个很好的解决方案,但它看起来像你有:WAR_DEPENDS关系倒转。如果'w'发布'otherWar'所依赖的服务,则otherWar将依赖于w。 – InverseFalcon

+0

@InverseFalcon非常感谢你指出 - 最后的查询也是错误的,因为我通过了'war'和'otherWar'并重用它们。这显然是错误的(它只提供直接连接),所以我修复并测试了查询。 –

3

[已更新]

寻找一个战争取决于另一个的方式

假设PUBLISHDEPENDSON关系总是在SERVICE节点WAR节点和月底开始,我相信这个查询会在其中找到war3(最终)取决于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

虽然在这种情况下可行,但如果'w':War是'war3',它将在路径上匹配另一个:WARs。据我所知,这种不同的关系可以与子图中的每一场战争相匹配,我认为这并不能满足需求。 'war3'从未发布过服务,所以没有:战争依赖于它。 – InverseFalcon

+0

@InverseFalcon是的,我正在更新我的答案,以更具体。你能想出一个更新的答案可能出错的方法吗? – cybersam

+0

很棒的编辑,MATCH对我来说很好看!我正准备评论有关显示仅获得不同的独立战争的查询,但你击败了我! – InverseFalcon

相关问题