我有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
节点使用{{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
个节点在给定范围内使用G
个S
节点(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
可能是网络中的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)
和Repeater
个节点,这些节点只与Endpoint
个节点连接,这些节点使用Gateway
所在的Sim
个节点范围。
关于我做错了什么的任何想法?
答案 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
个节点。
现在我收集所有C
和R
个节点,这些节点连接到G
以外的GroupGs
节点,我称之为badCandidates
。< / p>
最后,我获得C
集合中不在R
集合中的所有badCandidates
和G
个节点,并连接到GroupGs
中的{{1}}节点
这里有一个例子: [Neo4j Console Test]
我希望这有助于某人。