获取仅与具有范围属性的其他节点连接的节点

时间:2014-05-08 11:47:38

标签: neo4j cypher

我有4种类型的节点:S, G, RC

S个节点具有标识它们的idStr属性。

G类型的每个节点仅使用S个节点:(:G)-[:USES]->(:S)

C类型的每个节点都可以连接到多个RG个节点:(:C)-[:CONNECTED_TO]->(:R|:G)

R类型的每个节点都可以连接到多个RG个节点:(:R)-[:CONNECTED_TO]->(:R|:G)

问题:

给定idStr范围,我希望将所有RC个节点连接(直接或间接)仅与G节点使用{{1}在该范围内具有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个节点。的 [Neo4j Console Test]

我想做什么?

第一个匹配用于获取两件事:S个节点在给定范围内使用GS节点(idStr)和GroupGs连接到那些C节点的节点。

一旦我们得到了,我们必须检查那些G节点是否连接到更多C个节点(直接或通过G个节点)。那是第二场比赛。

现在我们必须检查每个R节点,如果连接到它的所有C节点(直接或通过G节点)都在R范围内。如果是这样,GroupGs节点(和C节点的路径中的R节点)是匹配的,这就是我想要得到的。

第二种方法(由@FrobberOfBits建议)

尝试只使用一个匹配项,因此我们确保G节点在匹配中是相同的:

n

结果是一样的。的 [Neo4j Console Test]

第三种方法(由@FrobberOfBits建议)

为问题提供语义,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 可能是网络中的CendpointRrepeaterG以及gateway S卡。

Sim个节点具有标识它们的Sim属性。

iccid类型的每个节点仅使用Gateway个节点:Sim

(:Gateway)-[:USES]->(:Sim)类型的每个节点都可以连接到多个EndpointRepeater个节点:Gateway

(:Endpoint)-[:CONNECTED_TO]->(:Repeater|:Gateway)类型的每个节点都可以连接到多个RepeaterRepeater个节点:Gateway

我正在尝试获取所有(:Repeater)-[:CONNECTED_TO]->(:Repeater|:Gateway)Repeater个节点,这些节点只与Endpoint个节点连接,这些节点使用Gateway所在的Sim个节点范围。

关于我做错了什么的任何想法?

2 个答案:

答案 0 :(得分:0)

您的查询确实让您选择的变量混淆了 - 将“a”绑定到标签S,将“b”绑定到标签G?后来在第二个匹配条款中将“c”绑定到“G”?这个查询将来很难调试,并且很难看到发生了什么;考虑将标签“G”绑定到“g”,或“gs”或类似,等等。

我认为你的问题是第二个匹配条款。第二个匹配子句中的(c:G)与第一个中的任何内容无关(即(b:G))。这意味着通过从某个节点到某些节点(c:G)的一组CONNECTED_TO *关系的路径与查询第一行上的复杂匹配无关。第二场比赛匹配标记为G的任何,而不仅仅是您在第一场比赛中指定的内容。

由于您声明的要求,第二场比赛很糟糕:

  

仅限使用具有该范围内的idStr的S节点的G节点

我没有你的测试数据,所以我无法验证这是否有效。但是这里有一些尝试:

MATCH (a:S)<-[:USES]-(b:G)<-[:CONNECTED_TO*]-(n:C),
      p=(n)-[:CONNECTED_TO*]->(b: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,GroupGs,COLLECT(c) AS gs
WHERE ALL(x IN gs WHERE x IN GroupGs)
RETURN cs

如果此处编辑的语法不完美,请道歉;这是一个复杂的查询,并将采取一些摆弄,但我认为第二个MATCH的位置和错误标签是你的问题。我的解决方案可能不完美,可能需要修改,但应该让你到那里。

答案 1 :(得分:0)

我想我终于明白了:

MATCH (a:S)<-[:USES]-(b:G)
WHERE a.idStr IN ['1a','b2','something']
WITH COLLECT(b) AS GroupGs
MATCH (c)-[:CONNECTED_TO*]->(d:G)
WHERE NOT d IN GroupGs
WITH COLLECT(c) AS badCandidates,GroupGs
MATCH (e)-[:CONNECTED_TO*]->(f:G)
WHERE NOT e IN badCandidates AND f IN GroupGs
RETURN e

首先,我得到GroupGs:所有使用G节点且在给定范围内具有S属性的idStr个节点。

现在我收集所有CR个节点,这些节点连接到G以外的GroupGs节点,我称之为badCandidates。< / p>

最后,我获得C集合中不在R集合中的所有badCandidatesG个节点,并连接到GroupGs中的{{1}}节点

这里有一个例子: [Neo4j Console Test]

我希望这有助于某人。