我有一个带有很多不同标签的图表。我现在想要选择给定标签子集的所有节点以及它们之间的所有关系。
我能够通过如何获取一组节点之间的所有关系?:
的解决方案获得预期结果MATCH (m:A|B|C)-[r]->(n:A|B|C)
RETURN m, r, n
但这感觉太重复了。如何避免指定标签集,即
A|B|C
,两次?
我尝试了以下操作,但它没有返回所有关系,而只返回节点与其自身之间的关系:
MATCH (n:A|B|C)-[r]->(n)
RETURN r, n
我正在寻找类似的东西
$labels = :A|B|C MATCH (m:$labels)-[r]->(n:$labels)
样本数据:
CREATE (a:A)-[:R]->(b:B)<-[:R]-(c:C)<-[:R]-(c)<-[:R]-(a)-[:R]->(d:D)
我希望查询返回:
不幸的是,动态标签在 Cypher 中还不是一个东西。
下面的查询更加冗长,但没有重复。因此,根据您的标签表达,这可能会有所回报:
MATCH (x:A|B|C)
WITH collect(x) as nodes
UNWIND nodes as m
UNWIND nodes as n
MATCH (m)-[r]->(n)
RETURN m, r, n;
这是一个比 Arne 提供的查询更有效的查询,也比提供两次标签更有效,有点奇怪,但查询配置文件显示了这一点。
MATCH (n:Person|Movie)
WITH collect(n) AS nodes
MATCH (n)-[r]->(o)
WHERE n IN nodes AND o IN nodes
RETURN n, r, o
由于您的查询仅重复标签列表一次,所以我不会说它“非常”重复:-)。
但是如果您愿意,您可以为所有具有所需标签的节点提供一个附加标签,例如
LABX
,然后执行:
MATCH (m:LABX)-[r]->(n:LABX) RETURN m, r, n
这将需要一点时间来设置(并且可能会在之后拆除),在创建这些节点期间会产生更多开销,并且会使用更多存储空间,但这是一种解决方案。
另一种解决方案是将 apoc.cypher.run 与生成的 Cypher 查询一起使用,其中标签来自同一字符串:
WITH ":A|B|C" AS labs
CALL apoc.cypher.run("MATCH (m" + labs +")-[r]->(n" + labs + ") RETURN m, r, n", {}) YIELD value
RETURN value.m AS m, value.r AS r, value.n AS n