neo4j - Cypher/neo4j 返回具有共同起点和终点的路径,终点按路径数过滤
问题描述
问题:我想使用 cypher 返回可以指定起点的路径,并按进入这些路径的终点的连接数进行过滤。
一些虚拟示例数据:
路径1:(a1:a)--(b1:b)--(c1:c)--(d1:d)
路径2:(a1:a)--(b2:b)--(c2:c)--(d1:d)
路径3:(a1:a)--(b3:b)--(c3:c)--(d2:d)
路径4:(a1:a)--(b2:b)--(c2:c)--(d3:d)
路径5:(a2:a)--(b4:b)--(c4:c)--(d3:d)
目标:我想带回所有以 a1 开头并以 dn 结尾的路径,其中从 a1 开始的路径到 dn 的关系计数> 1(或 2 或 3……在上面的示例中,我们将使用>1,但我希望能够针对关系计数可能更高的真实数据更改此设置)。
在上面的示例中,我想包括路径 1 和路径 2,因为它们都以 a1 开始并在 d1 终止,并且从 a1 开始并在 d1 终止的路径计数为 2(即 >1)。
路径 3 和 4 将被排除,因为尽管它们以 a1 开头,但没有其他以 a1 开头的路径以 d2 或 d3 终止。换句话说,d2 和 d3 在以 a1 开头的路径的上下文中是唯一的。
路径 5 将被排除,因为它不以 a1 开头,即使有 >1 条路径终止于 d3
除了能够在查询期间指定它们的标签并在最后得到构成路径的节点之外,所有中间节点基本上是无关紧要的。
我看过,但在其他地方找不到任何解决此问题的方法
解决方案
你的图表
为了方便可能的进一步答案和解决方案,我记下了我的图表创建声明:
CREATE
(a1:LabelA {name: 'A1'})-[:BELONGS_TO]->(b1:LabelB {name: 'B1'})-[:BELONGS_TO]->(c1:LabelC {name: 'C1'})
-[:BELONGS_TO]->(d1:LabelD {name: 'D1'}),
(a1)-[:BELONGS_TO]->(b2:LabelB {name: 'B2'})-[:BELONGS_TO]->(c2:LabelC {name: 'C2'})-[:BELONGS_TO]->(d1),
(a1)-[:BELONGS_TO]->(b3:LabelB {name: 'B3'})-[:BELONGS_TO]->(c3:LabelC {name: 'C3'})
-[:BELONGS_TO]->(d2:LabelD {name: 'D2'}),
(c2)-[:BELONGS_TO]->(d3:LabelD {name: 'D3'}),
(a2:LabelA {name: 'A2'})-[:BELONGS_TO]->(b4:LabelB {name: 'B4'})-[:BELONGS_TO]->(c4:LabelC {name: 'C4'})
-[:BELONGS_TO]->(d3);
解决方案
MATCH path = (:LabelA {name:'A1'})-[:BELONGS_TO*]->(endNode:LabelD)
WITH endNode, count(endNode) AS endNodeAmount WHERE endNodeAmount > 1
RETURN endNode.name AS endNode, endNodeAmount;
基本思想
- 第一行:定义任意长度的 A1 到 Dn 路径的模式
- 第二行:统计每个endNode(Dn)的出现次数并对其进行过滤,图1可以换成一个参数
$relationshipAmount
- 第三行:展示调查结果
结果
╒═════════╤═══════════════╕
│"endNode"│"endNodeAmount"│
╞═════════╪═══════════════╡
│"D1" │2 │
└─────────┴───────────────┘
扩展:变体“路径”
解决方案
如果您对节点 A1 和识别的 Dx 之间的路径感兴趣,可以依赖以下 Cypher 查询。
MATCH path = (startNode:LabelA {name:'A1'})-[:BELONGS_TO*]->(endNode:LabelD)
WITH collect(path) as paths, endNode WHERE size(paths) > 1
UNWIND paths as path RETURN path;
(鞠躬感谢@InverseFalcon 的优化想法。)
结果
╒═══════════════════════════════════════════════╕
│"path" │
╞═══════════════════════════════════════════════╡
│[{"name":"A1"},{},{"name":"B1"},{"name":"B1"},{│
│},{"name":"C1"},{"name":"C1"},{},{"name":"D1"}]│
├───────────────────────────────────────────────┤
│[{"name":"A1"},{},{"name":"B2"},{"name":"B2"},{│
│},{"name":"C2"},{"name":"C2"},{},{"name":"D1"}]│
└───────────────────────────────────────────────┘
推荐阅读
- node.js - SVGO 配置文件
- python - 使用键将列表转换为字典列表
- r - 处理 JSON 文件并将其下载到特定文件夹中
- java - 为什么 repaint() 不在摆动计时器中调用paintcomponent?
- python - Selenium + Python 数据抓取不起作用。Shopee 的产品名称未保存在 csv 文件中
- next.js - 我看不到 Next.js 默认页面
- r - 替换矩阵中的重复项
- reactjs - 如何在 react-native-gifted-chat 中左右显示聊天消息
- go - 有没有办法将 json 查询转换为人类可用的 Kibana 链接?
- javascript - 如何根据键对对象数组进行排序并设置一个在顺序更改时应递增的附加键?