Neo4j Cypher Query 根据开始结束条件列出具有单一关系的节点路径
Neo4j Cypher Query to list paths of nodes with a single relation based on a start-end condition
我的图表只有一种关系,没有标签,没有属性等。刚刚定向关系称为 NT
.
每个节点都有一组属性。基于该属性,我想显示起始节点具有 codeqty > 0
以及 codes
属性 的所有路径(链),但所有下一个节点都是 codeqty = 0
(与空 codes
属性) 直到链中出现另一个节点 codeqty > 0
且其文本不同 codes
属性 或不管 codes
属性.
所以我需要像这个伪代码模式一样获取任意深度的所有节点:
(n)-[:NT]->(m) where n.codeqty > 0 and m.codeqty = 0
(作为起点条件)
...
(m)-[:NT]->(p) where m.codeqty = 0 and p.codeqty > 0 and n.codes <> p.codes
(作为终点条件)
或者只是通过遇到下一个 p.codeqty > 0
而不管 codes
属性 喜欢
(m)-[:NT]->(p) where m.codeqty = 0 and p.codeqty > 0
(作为终点条件)
我需要显示以 (n)->...->(m)
开始并以 (m)
结束的(最短或任何)路径,因为 (p)
不属于停止条件下的此链。
是否也可以作为选项受深度限制?
顺便说一下,是否真的可以通过使用节点属性而不是关系属性来做到这一点?如果没有,请制作一个片段说明如何做。
非常感谢!
PS。欢迎使用任何版本的 neo4j。我使用的是最新的 2.20
UPD
我有这样的想法(n、p、m 变量可能与上面不同,但你明白了)
MATCH (n)-[:NT]->(p)<-[:NT]-(m) WHERE n.codes = m.codes AND n.codeqty > 0 AND p.codeqty = 0
2跳好像还可以:
MATCH (n)-[:NT*1..2]->(p)<-[:NT*1..2]-(m) WHERE n.codes = m.codes AND n.codeqty > 0 AND p.codeqty = 0
从 3 个或更多跃点开始,它开始搞砸了:
MATCH (n)-[:NT*1..3]->(p)<-[:NT*1..3]-(m) WHERE n.codes = m.codes AND n.codeqty > 0 AND p.codeqty = 0
据我所能手动检查。
我觉得可以通过使用 SQL window 之类的函数(例如 PARTITION BY ROW_NUMBER for SQL Server 之类的函数来完美地完成和过滤掉它。我不知道那种爵士乐有任何 Cypher 等价物。你知道吗?!
您正在寻找的是像您上一个示例中那样的可变长度路径,结合了集合函数和谓词。
MATCH path = (n)-[:NT*1..3]->(p)
WHERE n.codeqty > 0
AND ALL(x in tail(nodes(path)) WHERE x.codeqty = 0)
AND NOT (p)-[:NT]->()
如果您想比较集合中的节点,您将不得不求助于基于索引的访问
WITH nodes(path) as nodes
AND ALL(idx in range(0,size(nodes)-2) WHERE nodes[idx].codes <> nodes[idx+1].codes)
我的图表只有一种关系,没有标签,没有属性等。刚刚定向关系称为 NT
.
每个节点都有一组属性。基于该属性,我想显示起始节点具有 codeqty > 0
以及 codes
属性 的所有路径(链),但所有下一个节点都是 codeqty = 0
(与空 codes
属性) 直到链中出现另一个节点 codeqty > 0
且其文本不同 codes
属性 或不管 codes
属性.
所以我需要像这个伪代码模式一样获取任意深度的所有节点:
(n)-[:NT]->(m) where n.codeqty > 0 and m.codeqty = 0
(作为起点条件)
...
(m)-[:NT]->(p) where m.codeqty = 0 and p.codeqty > 0 and n.codes <> p.codes
(作为终点条件)
或者只是通过遇到下一个 p.codeqty > 0
而不管 codes
属性 喜欢
(m)-[:NT]->(p) where m.codeqty = 0 and p.codeqty > 0
(作为终点条件)
我需要显示以 (n)->...->(m)
开始并以 (m)
结束的(最短或任何)路径,因为 (p)
不属于停止条件下的此链。
是否也可以作为选项受深度限制?
顺便说一下,是否真的可以通过使用节点属性而不是关系属性来做到这一点?如果没有,请制作一个片段说明如何做。
非常感谢!
PS。欢迎使用任何版本的 neo4j。我使用的是最新的 2.20
UPD
我有这样的想法(n、p、m 变量可能与上面不同,但你明白了)
MATCH (n)-[:NT]->(p)<-[:NT]-(m) WHERE n.codes = m.codes AND n.codeqty > 0 AND p.codeqty = 0
2跳好像还可以:
MATCH (n)-[:NT*1..2]->(p)<-[:NT*1..2]-(m) WHERE n.codes = m.codes AND n.codeqty > 0 AND p.codeqty = 0
从 3 个或更多跃点开始,它开始搞砸了:
MATCH (n)-[:NT*1..3]->(p)<-[:NT*1..3]-(m) WHERE n.codes = m.codes AND n.codeqty > 0 AND p.codeqty = 0
据我所能手动检查。
我觉得可以通过使用 SQL window 之类的函数(例如 PARTITION BY ROW_NUMBER for SQL Server 之类的函数来完美地完成和过滤掉它。我不知道那种爵士乐有任何 Cypher 等价物。你知道吗?!
您正在寻找的是像您上一个示例中那样的可变长度路径,结合了集合函数和谓词。
MATCH path = (n)-[:NT*1..3]->(p)
WHERE n.codeqty > 0
AND ALL(x in tail(nodes(path)) WHERE x.codeqty = 0)
AND NOT (p)-[:NT]->()
如果您想比较集合中的节点,您将不得不求助于基于索引的访问
WITH nodes(path) as nodes
AND ALL(idx in range(0,size(nodes)-2) WHERE nodes[idx].codes <> nodes[idx+1].codes)