やってみる
路線図とかをインプットしてみて最短距離検索とかやる場合、どうやるのかな?
と思っていたら、参考URLがあったので、やってみる!
※正直しっかり理解できてません。。。
山手線の路線図を作るだけ。
import urllib.request as urllib
from xml.dom import minidom, Node
from neo4j.v1 import GraphDatabase, basic_auth
def get_station_info(line_cd):
join_list = []
url = 'http://www.ekidata.jp/api/n/' + str(line_cd) + '.xml'
dom = minidom.parse(urllib.urlopen(url))
all_station = set()
all_kukan = dict()
for join_node in dom.getElementsByTagName('station_join'):
for join_node_child in join_node.childNodes:
if join_node_child.nodeType == Node.TEXT_NODE:
continue
name = join_node_child.nodeName
value = join_node_child.childNodes.item(0).nodeValue
if name == 'station_name1':
station_name1 = value
all_station.add(value)
elif name == 'station_name2':
station_name2 = value
all_station.add(value)
all_kukan[station_name1] = station_name2
return all_station, all_kukan
def connect_srv():
driver = GraphDatabase.driver("bolt://localhost", auth=basic_auth('neo4j', 'neo4j'))
return driver
if __name__ == '__main__':
all_station, all_kukan = get_station_info(11302)
driver = connect_srv()
session = driver.session()
q = 'match (a) optional match (a)-[r]-() delete a,r'
session.run(q)
for station in all_station:
q = 'create (a:' + station + '{name:' + "'" + station + "'" + '})'
session.run(q)
for src,dst in all_kukan.items():
q = 'match (a:' + src + '{name:' + "'" + src + "'" + '}), '
q += '(b:' + dst + '{name:' + "'" + dst + "'" + '}) '
q += 'merge (a)-[c:rosen]->(b)'
session.run(q)
session.close()
上記を実行すると、こんなグラフが生成される。
駅の色に意味なし。neo4jが登録順にラベルの色をつけているためと想定される。
駅間の距離も意味なし。
内・外回りのリレーションを作ろうと思ったが、双方向リレーションを設定するのは、非推奨との情報あり。
Neo4jで学ぶGraph DB入門 - omotenashi-mind
Modelling Data in Neo4j: Bidirectional Relationships
参照時は、方向性を無視した探し方で対応するのが良いとのこと。
最短距離を検索
GUIから以下クエリを実行
池袋→東京
MATCH (from: 池袋 {name:'池袋'}), (to: 東京 {name:'東京'}), path=allShortestPaths((from)-[*]-(to)) return from,to,path
池袋→新宿
MATCH (from: 池袋 {name:'池袋'}), (to: 新宿 {name:'新宿'}), path=allShortestPaths((from)-[*]-(to)) return from,to,path