1、前言
打開手機‘北京地鐵’APP,輸入起始點:霍營,終點:北京南站,發現系統給咱們推薦了兩條路線。
最短期路線與最少換乘路線,而且分別給出了耗時與乘坐里程費。看到這裏,不由開啓了靚仔疑問,假如給你地鐵站相關數據,如何構建這樣的關係網絡呢?(儘可能少寫代碼,畢竟我這我的懶的不行,花最少的功夫,整最炫的效果,咦)
html
1.整理地鐵站點數據,處理成echarts圖表所須要的結構
2.整理地鐵站點數據,本身寫代碼實現,能實現(好累啊…)
3.整理地鐵站點數據,導入 Neo4j 中,點擊查看
sql
分析:方案一,不只要處理數據還要搞echarts樣式,算了吧。方案二,直接PASS,仍是方案三省力,正好個人電腦上以前安裝過 Neo4j 圖數據庫,哈哈哈,開搞開搞!
軟件下載地址:http://doc.we-yun.com:1008/neo4j-chs
軟件安裝教程:https://www.cnblogs.com/jstarseven/p/9546555.html
數據庫
![Neo4j 地鐵關係網][1]瀏覽器
2、數據準備
既然須要展現地鐵關係,那麼首先須要的就是北京全部地鐵站的信息,以及站點之間的關係,距離,耗時。搜索了一圈,最後在北京地鐵官方網站,發現了所有地鐵線路,站點名稱,站點與站點之間距離等信息。可是缺乏了具體站點與站點之間的乘車耗時,行吧,先將就着用吧!具體數據樣例以下:網絡
![Neo4j 地鐵關係網][2]數據來源地址:https://www.bjsubway.com/station/zjgls/#echarts
站點關係
一共18條線路,一頓複製粘貼和 Notepad++ 文本替換以後,咱們獲得了一個 Excel文件,包含了全部站點之間的關係數據,以下:網站
![Neo4j 地鐵關係網][3]獲取站點
複製全部站點進入Excel文件的某一個sheet,選擇數據去重,獲得全部站點名稱。url
![Neo4j 地鐵關係網][4]處理CSV
將站點關係與站點數據處理成CSV文件格式,方便導入 Neo4j 數據庫中,創建圖節點與關係。操做也就是 notepad++ 替換‘ ’爲‘,’,另存爲 .CSV 文件,具體獲得下列文件。(由於方便 Neo4j 數據庫不一樣的路線顯示不一樣的顏色,我特意將站點關係數據拆解成了多個地鐵線的CSV文件,若是不考慮顯示,能夠一個CSV文件,導入站點關係便可)spa
![Neo4j 地鐵關係網][9]備註:將全部CSV文件,放入 Neo4j 安裝目錄下的 import 文件夾中(沒有就新建),以下:.net
![Neo4j 地鐵關係網][5]3、創建地鐵關係網
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瀏覽器配置
![Neo4j 地鐵關係網][6]2.cypher語句執行過程
![Neo4j 地鐵關係網][7]3.地鐵關係網效果
![Neo4j 地鐵關係網][8]4、路徑檢索
以‘霍營’與‘北京南站’地鐵站爲例,檢索具體一下路徑:
最少站點路徑
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
最少耗時路徑
很遺憾,由於沒有找到北京地鐵每站之間具體的耗時數據,因此此處檢索不出來,行吧,我太難了。
5、總結
1)數據整理涉及節點數據,節點關係數據,可在導入CSV時一併建立;
2)Cypher 是 借鑑了sql語句的 Neo4j 數據庫操做語句;
3)(a)-[*…20]->(b):表示路徑長度的最大值是20,起始節點是a,終止節點是b;
4)一次執行多條語句,Neo4j瀏覽器須要開啓多語句執行配置;