关于图数据库:动手构建地铁关系网实现最短路径查询

31次阅读

共计 4775 个字符,预计需要花费 12 分钟才能阅读完成。

一、前言

关上手机‘北京地铁 ’APP,输出起始点:霍营,起点:北京南站,发现零碎给咱们举荐了两条路线。
最短时间路线与起码换乘路线,并且别离给出了耗时与乘坐里程费。看到这里,不禁开启了靓仔疑难,如果给你地铁站相干数据,如何构建这样的关系网络呢?(尽量少写代码,毕竟我这个人懒的不行,花起码的功夫,整最炫的成果,咦)

1. 整顿地铁站点数据,解决成 echarts 图表所须要的构造
2. 整顿地铁站点数据,本人写代码实现,能实现(好累啊 …)
3. 整顿地铁站点数据,导入 Neo4j 中,点击查看

剖析:计划一,不仅要解决数据还要搞 echarts 款式,算了吧。计划二,间接 PASS,还是计划三省力,正好我的电脑上之前装置过 Neo4j 图数据库,哈哈哈,开搞开搞!
软件下载地址:http://doc.we-yun.com:1008/neo4j-chs
软件装置教程:https://www.cnblogs.com/jstar…

二、数据筹备

既然须要展现地铁关系,那么首先须要的就是北京所有地铁站的信息,以及站点之间的关系,间隔,耗时。搜寻了一圈,最初在北京地铁官方网站,发现了全副地铁线路,站点名称,站点与站点之间间隔等信息。然而短少了具体站点与站点之间的乘车耗时,行吧,先将就着用吧!具体数据样例如下:

数据起源地址:https://www.bjsubway.com/stat…

站点关系

一共 18 条线路,一顿复制粘贴和 Notepad++ 文本替换之后,咱们失去了一个 Excel 文件,蕴含了所有站点之间的关系数据,如下:

获取站点

复制所有站点进入 Excel 文件的某一个 sheet,抉择数据去重,失去所有站点名称。

解决 CSV

将站点关系与站点数据处理成 CSV 文件格式,不便导入 Neo4j 数据库中,建设图节点与关系。操作也就是 notepad++ 替换‘’为‘,’, 另存为 .CSV 文件,具体失去下列文件。(因为不便 Neo4j 数据库不同的路线显示不同的色彩,我顺便将站点关系数据拆解成了多个地铁线的 CSV 文件,如果不思考显示,能够一个 CSV 文件,导入站点关系即可)

备注:将所有 CSV 文件,放入 Neo4j 装置目录下的 import 文件夹中(没有就新建),如下:

文件下载地址:https://files-cdn.cnblogs.com…

三、建设地铁关系网

Neo4j 反对导入本地以及网络资源中的 CSV 文件数据,并且能够从 CSV 文件数据中,间接建设图形节点以及节点关系。具体 cypher 语句,如下:

建设地铁站点

LOAD CSV WITH HEADERS  FROM "file:///station.csv" AS line
MERGE (p:Station{id:line.id,name:line.name});

建设站点连贯

LOAD CSV WITH HEADERS FROM "file:///line1.csv" AS line1
match (from1:Station{name:line1.sn}),(to1:Station{name:line1.en})
merge (from1)-[r1: 一号线{jl:line1.jl,xl:line1.xl}]->(to1);

LOAD CSV WITH HEADERS FROM "file:///line2.csv" AS line2
match (from2:Station{name:line2.sn}),(to2:Station{name:line2.en})
merge (from2)-[r2: 二号线{jl:line2.jl,xl:line2.xl}]->(to2);

LOAD CSV WITH HEADERS FROM "file:///line4.csv" AS line4
match (from4:Station{name:line4.sn}),(to4:Station{name:line4.en})
merge (from4)-[r4: 四号线{jl:line4.jl,xl:line4.xl}]->(to4);

LOAD CSV WITH HEADERS FROM "file:///line5.csv" AS line5
match (from5:Station{name:line5.sn}),(to5:Station{name:line5.en})
merge (from5)-[r5: 五号线{jl:line5.jl,xl:line5.xl}]->(to5);

LOAD CSV WITH HEADERS FROM "file:///line6.csv" AS line6
match (from6:Station{name:line6.sn}),(to6:Station{name:line6.en})
merge (from6)-[r6: 六号线{jl:line6.jl,xl:line6.xl}]->(to6);

LOAD CSV WITH HEADERS FROM "file:///line7.csv" AS line7
match (from7:Station{name:line7.sn}),(to7:Station{name:line7.en})
merge (from7)-[r7: 七号线{jl:line7.jl,xl:line7.xl}]->(to7);

LOAD CSV WITH HEADERS FROM "file:///line8.csv" AS line8
match (from8:Station{name:line8.sn}),(to8:Station{name:line8.en})
merge (from8)-[r8: 八号线{jl:line8.jl,xl:line8.xl}]->(to8);

LOAD CSV WITH HEADERS FROM "file:///line9.csv" AS line9
match (from9:Station{name:line9.sn}),(to9:Station{name:line9.en})
merge (from9)-[r9: 九号线{jl:line9.jl,xl:line9.xl}]->(to9);

LOAD CSV WITH HEADERS FROM "file:///line10.csv" AS line10
match (from10:Station{name:line10.sn}),(to10:Station{name:line10.en})
merge (from10)-[r10: 十号线{jl:line10.jl,xl:line10.xl}]->(to10);

LOAD CSV WITH HEADERS FROM "file:///line13.csv" AS line13
match (from13:Station{name:line13.sn}),(to13:Station{name:line13.en})
merge (from13)-[r13: 十三号线{jl:line13.jl,xl:line13.xl}]->(to13);

LOAD CSV WITH HEADERS FROM "file:///line14.csv" AS line14
match (from14:Station{name:line14.sn}),(to14:Station{name:line14.en})
merge (from14)-[r14: 十四号线{jl:line14.jl,xl:line14.xl}]->(to14);

LOAD CSV WITH HEADERS FROM "file:///line15.csv" AS line15
match (from15:Station{name:line15.sn}),(to15:Station{name:line15.en})
merge (from15)-[r15: 十五号线{jl:line15.jl,xl:line15.xl}]->(to15);

LOAD CSV WITH HEADERS FROM "file:///linebt.csv" AS linebt
match (frombt:Station{name:linebt.sn}),(tobt:Station{name:linebt.en})
merge (frombt)-[rbt: 八通线{jl:linebt.jl,xl:linebt.xl}]->(tobt);

LOAD CSV WITH HEADERS FROM "file:///linecp.csv" AS linecp
match (fromcp:Station{name:linecp.sn}),(tocp:Station{name:linecp.en})
merge (fromcp)-[rcp: 昌平线{jl:linecp.jl,xl:linecp.xl}]->(tocp);

LOAD CSV WITH HEADERS FROM "file:///lineyz.csv" AS lineyz
match (fromyz:Station{name:lineyz.sn}),(toyz:Station{name:lineyz.en})
merge (fromyz)-[ryz: 亦庄线{jl:lineyz.jl,xl:lineyz.xl}]->(toyz);

LOAD CSV WITH HEADERS FROM "file:///linedx.csv" AS linedx
match (fromdx:Station{name:linedx.sn}),(todx:Station{name:linedx.en})
merge (fromdx)-[rdx: 大兴线{jl:linedx.jl,xl:linedx.xl}]->(todx);

LOAD CSV WITH HEADERS FROM "file:///linefs.csv" AS linefs
match (fromfs:Station{name:linefs.sn}),(tofs:Station{name:linefs.en})
merge (fromfs)-[rfs: 房山线{jl:linefs.jl,xl:linefs.xl}]->(tofs);

LOAD CSV WITH HEADERS FROM "file:///linejc.csv" AS linejc
match (fromjc:Station{name:linejc.sn}),(tojc:Station{name:linejc.en})
merge (fromjc)-[rjc: 机场线{jl:linejc.jl,xl:linejc.xl}]->(tojc);

执行成果

备注:Neo4j 浏览器须要开启多语句执行配置,否则会报语句执行谬误,配置界面如下:

1.Neo4j 浏览器配置

2.cypher 语句执行过程

3. 地铁关系网成果

四、门路检索

以‘霍营 ’与‘ 北京南站’地铁站为例,检索具体一下门路:

起码站点门路

MATCH (p1:Station {name:"霍营"}),(p2:Station{name:"北京南站"}),p=shortestpath((p1)-[*]-(p2)) RETURN p

最短途程门路

MATCH p=(b:Station{name:"霍营"})-[*..20]->(d:Station{name:"北京南站"}) WITH p,reduce(s = 0, r IN rels(p) | s + r.jl) AS dist return p ORDER BY dist DESC limit 1

起码耗时门路

很遗憾,因为没有找到北京地铁每站之间具体的耗时数据,所以此处检索不进去,行吧,我太难了。

五、总结

1)数据整顿波及节点数据,节点关系数据,可在导入 CSV 时一并创立;
2)Cypher 是 借鉴了 sql 语句的 Neo4j 数据库操作语句;
3)(a)-[*..20]->(b):示意门路长度的最大值是 20,起始节点是 a,终止节点是 b;
4)一次执行多条语句,Neo4j 浏览器须要开启多语句执行配置;

正文完
 0