【发布时间】:2014-05-08 11:47:38
【问题描述】:
我有 4 种类型的节点:S, G, R 和 C
S 节点具有标识它们的idStr 属性。
G 类型的每个节点只使用一个 S 节点:(:G)-[:USES]->(:S)
C 类型的每个节点都可以连接到多个 R 或 G 节点:(:C)-[:CONNECTED_TO]->(:R|:G)
R 类型的每个节点都可以连接到多个 R 或 G 节点:(:R)-[:CONNECTED_TO]->(:R|:G)
问题:
给定一个idStr 范围,我希望所有R 和C 节点仅连接(直接或间接)到G 节点,这些节点使用S 节点和idStr范围。
我实现的最接近的方法是:
MATCH (a:S)<-[:USES]-(b:G)<-[:CONNECTED_TO*]-(n:C)
WHERE a.idStr IN ['1a','b2','something']
WITH COLLECT(DISTINCT b) AS GroupGs
MATCH p=(n)-[:CONNECTED_TO*]->(c:G)
WITH FILTER(x IN NODES(p) WHERE NOT x:G) AS cs,GroupGs,COLLECT(c) AS gs
WHERE ALL(x IN gs WHERE x IN GroupGs)
RETURN cs
但仍有一些连接到G 节点的节点使用不在范围内的S 节点。 [Neo4j Console Test]
我想做什么?
第一个匹配用于获取两件事:G 节点使用 S 节点,idStr 在给定范围 (GroupGs) 和连接到这些 G 节点的 C 节点.
一旦我们得到它,我们必须检查那些C 节点是否连接到更多G 节点(直接或通过R 节点)。那是第二场比赛。
现在我们必须检查每个C 节点是否所有连接到它的G 节点(直接或通过R 节点)都在GroupGs 范围内。如果是这样,那C 节点(以及G 节点路径中的R 节点)是匹配的,这就是我想要得到的。
第二种方法(@FrobberOfBits 建议)
尝试只使用一个匹配,所以我们确定n 节点在匹配中是相同的:
MATCH (a:S)<-[:USES]-(b:G)<-[:CONNECTED_TO*]-(n:C), p=(n)-[:CONNECTED_TO*]->(c:G)
WHERE a.idStr IN ['1a','b2','something']
WITH COLLECT(DISTINCT b) AS GroupGs, FILTER(x IN NODES(p) WHERE NOT x:G) AS cs,COLLECT(c) AS gs
WHERE ALL(x IN gs WHERE x IN GroupGs)
RETURN cs
结果是一样的。 [Neo4j Console Test]
第三种方法(@FrobberOfBits 建议)
为问题赋予语义,C 可能是网络中的 endpoint,R 一个 repeater,G 一个 gateway 和 S 一个 Sim 卡。
Sim 节点具有标识它们的iccid 属性。
Gateway 类型的每个节点只使用一个 Sim 节点:(:Gateway)-[:USES]->(:Sim)
Endpoint 类型的每个节点都可以连接到多个 Repeater 或 Gateway 节点:(:Endpoint)-[:CONNECTED_TO]->(:Repeater|:Gateway)
Repeater 类型的每个节点都可以连接到多个 Repeater 或 Gateway 节点:(:Repeater)-[:CONNECTED_TO]->(:Repeater|:Gateway)
我正在尝试获取刚刚连接到Gateway 节点的所有Repeater 和Endpoint 节点,这些节点使用Sim 节点,其iccid 在一个范围内。
知道我做错了什么吗?
【问题讨论】: