Neo4j 获取仅连接到具有范围内属性的其他节点的节点
我有4种类型的节点:Neo4j 获取仅连接到具有范围内属性的其他节点的节点,neo4j,cypher,Neo4j,Cypher,我有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 我最接
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
结果是一样的[]
第三种方法(由@frobberoffits建议)
就问题的语义而言,C
可能是网络中的端点,R
a中继器
,G
a网关
和S
aSim
卡
Sim
节点具有标识它们的iccid
属性
Gateway
类型的每个节点只使用一个Sim
节点:(:Gateway)-[:uses]->(:Sim)
端点
类型的每个节点都可以连接到多个中继器
或网关
节点:(:端点)-[:连接到]->(:中继器|:网关)
中继器类型的每个节点可以连接到多个中继器
或网关
节点:(:中继器)-[:连接到]->(:中继器|:网关)
我正在尝试获取所有刚刚连接到Gateway
节点的中继器
和端点
节点,这些节点正在使用Sim
节点,其iccid
在一个范围内
你知道我做错了什么吗?你的查询真的把事情和你选择的变量搞混了——把“a”绑定到标签S,把“b”绑定到标签G?后来在第二个匹配子句中将“c”约束为“G”?这个查询将来很难调试,并且很难看到发生了什么;考虑绑定标签“G”到“G”,或“GS”,或类似,等等。p>
我认为你的问题在于第二个匹配条款。第二个match子句中的(c:G)与第一个match子句中的任何内容(即(b:G))无关。这意味着通过一组从某个节点到某个节点(c:G)的连接的_-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
匹配(a:S)我想我终于得到了:
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
匹配(a:S)(d:G)
在GroupGs中没有d的地方
以COLLECT(c)作为候选项,GroupGs
匹配(e)-[:连接到*]->(f:G)
其中不包括BAD候选者中的e和GroupGs中的f
返回e
首先,我得到GroupGs
:在给定范围内使用S
节点且具有idStr
属性的所有G
节点
现在,我收集所有连接到G
节点的C
和R
节点,这些节点不在GroupGs
中,我将它们称为badCandidates
最后,我得到所有C
和R
节点,这些节点不在badCandidates
集合中,并且连接到GroupGs
中的G
节点
这里有一个例子:
我希望这对某人有所帮助。如果符号混乱,我很抱歉,@frobberoffits第二个match子句中的(c:G)节点确实与第一个match子句中的任何内容都没有必要关联。我已经编辑了问题,添加了我想做什么的部分?为了澄清这一点。谢谢你的努力!楚兹,谢谢你,但我认为你的第二场比赛仍然有问题。在您的说明中,您说:“我们必须检查这些C节点是否连接到更多的G节点(直接或通过R节点)。这是第二个匹配。”当您说这些C节点,第二个匹配中的节点时,您仅指节点“n”。在你的第一场比赛中,这个“n”与任何事情都没有关系。所以n不是那些C节点,n是任何节点(不限于C),我如何绑定它们?我以前使用代码[…]和n,COLLECT(DISTINCT b)作为GroupGs[…]
尝试绑定它们,但结果是一样的,所以我删除了n
。像我建议的那样,在第一个匹配中创建第二个子句,引用n。我不认为第一场比赛中的“n”这个名字会延续到第二场比赛。你可能是对的。这个查询很复杂,正如我所说的,用抽象标签很难理解。我有一种感觉,如果我们知道S、G和C是什么,以及语义是什么,这会更有意义。如果我们知道这一点,也许还会有另一种查询方法可以建议(而不是调整这个方法)。祝你好运
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