2014-12-27 35 views
3

我的問題是我有一個圖表,有很多代表巴士站點的節點。 我該如何包含總線信息,比如哪些總線在節點之間可用。Neo4j巴士路線應用程序建模

我想創建一個節點之間的巴士關係,將有兩個節點之間的所有巴士信息和兩個站點之間的關係屬性標記距離。

 buses[500A,182A],distance:500m  buses[121B,542W,222A,111Z],distance:400m 

Like A ----------------------------------------- -------------->乙---------------------------------- -------------------------> C

因此,我如何找出總線或總線(如果沒有直接路徑可用)以從A到達M?

首先我會找出路徑(neo4j查詢),如何從A到達M。

說我的路徑是

buses[11A],distance:1000m buses[11A],distance:250m buses[13B,100A],distance:2000m 

一個---------------------------------- ------->→----------------------------------->ñ---- ---------------------------------------> M

問題是我如何以編程方式檢查是否有可用的M到M的直接總線,或者我如何在兩者之間交換總線。

根據上述情況,我可以從A到N到11A,然後從N到M,可以是13B或100A。

我必須以編程方式做到這一點。

我想檢索兩個站之間的所有可能的路徑以及路徑的總距離和總線信息。

+0

你希望儘量減少距離或轉讓的數量? –

+0

我想獲得所有可能的路線與巴士轉乘信息alonng與每個路徑的總dstancce。 –

回答

8

您的模型需要更多graphy-y。也就是說,我不認爲你應該有一個關於Stop節點與總線信息之間關係的數組屬性。相反,巴士應該是自己的關係,表明他們停在哪個站點。請看下面的示例數據:

CREATE (a:Stop {name:'A'}), 
     (b:Stop {name:'B'}), 
     (c:Stop {name:'C'}), 
     (d:Stop {name:'D'}), 

     (a)-[:NEXT {distance:1}]->(b), 
     (b)-[:NEXT {distance:2}]->(c), 
     (c)-[:NEXT {distance:3}]->(d), 

     (b1:Bus {id:1}), 
     (b2:Bus {id:2}), 
     (b3:Bus {id:3}), 

     (b1)-[:STOPS_AT]->(a), 
     (b1)-[:STOPS_AT]->(b), 
     (b2)-[:STOPS_AT]->(a), 
     (b2)-[:STOPS_AT]->(b), 
     (b2)-[:STOPS_AT]->(c), 
     (b3)-[:STOPS_AT]->(b), 
     (b3)-[:STOPS_AT]->(c), 
     (b3)-[:STOPS_AT]->(d); 

圖表現在看起來是這樣的:

model

在這種模式下,很容易發現,轉讓的數量爲最小的行程也將返回所有必要的傳輸信息(如果適用)。例如,所有的最短路線(最短轉讓#而言)從A到d:

MATCH (a:Stop {name:'A'}), (d:Stop {name:'D'}) 
MATCH p = allShortestPaths((a)-[:STOPS_AT*]-(d)) 
RETURN EXTRACT(x IN NODES(p) | CASE WHEN x:Stop THEN 'Stop ' + x.name 
            WHEN x:Bus THEN 'Bus ' + x.id 
           ELSE '' END) AS itinerary 

三條路線中發現,它們都具有一個轉移:

Stop A, Bus 2, Stop C, Bus 3, Stop D 
Stop A, Bus 1, Stop B, Bus 3, Stop D 
Stop A, Bus 2, Stop B, Bus 3, Stop D 

當然,你可以不過,您可以使用EXTRACT()函數返回此信息。

另一個例子。從A中查找一個行程到C:

MATCH (a:Stop {name:'A'}), (c:Stop {name:'C'}) 
MATCH p = allShortestPaths((a)-[:STOPS_AT*]-(c)) 
RETURN EXTRACT(x IN NODES(p) | CASE WHEN x:Stop THEN 'Stop ' + x.name 
            WHEN x:Bus THEN 'Bus ' + x.id 
           ELSE '' END) 

一種途徑被發現,並沒有轉移:

Stop A, Bus 2, Stop C 

請讓我知道如果這個回答你的問題。

編輯:爲了獲得距離:

MATCH (a:Stop {name:'A'}), (d:Stop {name:'D'}) 
MATCH route = allShortestPaths((a)-[:STOPS_AT*]-(d)), 
     stops = (a)-[:NEXT*]->(d) 
RETURN EXTRACT(x IN NODES(route) | CASE WHEN x:Stop THEN 'Stop ' + x.name 
             WHEN x:Bus THEN 'Bus ' + x.id 
            ELSE '' END) AS itinerary, 
     REDUCE(d = 0, x IN RELATIONSHIPS(stops) | d + x.distance) AS distance 


          itinerary distance 
Stop A, Bus 1, Stop B, Bus 3, Stop D   6 
Stop A, Bus 2, Stop B, Bus 3, Stop D   6 
Stop A, Bus 2, Stop C, Bus 3, Stop D   6 
+0

感謝妮可,這是我正在尋找的。我添加了距離屬性到停止之間的NEXT關係。我試着這個查詢來從每種可能的方式獲得總距離,但它返回null。 (匹配:(停止{名稱:'A'}),(c:停止{名稱:'C'}) MATCH p = allShortestPaths((a) - [:STOPS_AT *] - (c)) RETURN EXTRACT (x IN NODES(p)| CASE WHEN x:Stop THEN'Stop'+ x.name WHEN x:Bus THEN'Bus'+ x.id ELSE''END),reduce(distance = 0,r in relationships (p)| distance + r.distance)as Distance'.Can you explain how this query is working in internal。 –

+1

我沒有意識到距離是一個因素 - 你可以編輯你的問題,包括?你的上面的查詢返回null,因爲你匹配'STOPS_AT'關係,而不是'NEXT'關係。 –

0

由於您可以在同一個節點之間創建多個關係,因此我建議爲每個總線創建一個關係。所以從你的例子:

A<-----------------B<-------------------------------C 
    buses[180Q,171B]  buses[80A,43B,121S] 

你可以這樣做:

<somehow MATCH on A and B> 
CREATE B-[:connects_to {bus: '180Q'}]->A 
CREATE B-[:connects_to {bus: '171B'}]->A 

等等...

這樣,你可以做

MATCH path=(start {id: '123'})-[:connects_to {bus: '180Q'}*1..10]-(end: {id: '321'}) 
UNWIND relationships(path) AS hop 
WITH path, hop 
WITH path, collect(DISTINCT hop.bus) AS busses 
WHERE length(busses) <= 2 
RETURN path 

老實說我我從未同時使用關係屬性匹配作爲可變長度規範,但我想它可以工作

+0

我明白我可以在節點之間創建多個關係。但@Brian問題是即使當我通過密碼查詢得到節點之間的最短路徑時,我仍然必須以編程方式檢查密碼查詢的路徑返回以表示站上的總線交換。該查詢不提供我在哪裏交換,它只是給我從A到B的最短路徑,並且有巴士詳細信息到達目的地。我希望我能夠告訴你我的問題。 –

+0

啊,我想也許我明白了。你想找到最短的路線,包括轉移(一站下車,另一條路線)? –

+0

是@布萊恩那是我在找什麼。有什麼方法 –

0

我嘗試了很多密碼查詢,但無法得到我在找的東西,公交車信息。直到現在我的查詢是。

MATCH (from:Stop { name:"A" }), (to:Stop { name: "S"}) , path = (from)-[:CONNECTED*]->(to) 
unwind relationships(path) as hop 
RETURN extract(n IN nodes(path)| n.name) AS Shortest_Route,collect(hop.Buses) as Buses,length(path) as Stop_Count, 
reduce(distance = 0, r in relationships(path) | distance+r.distance) AS Shortest_Distance 
ORDER BY Shortest_Distance ASC 
LIMIT 1 . 

我發現很難獲得巴士轉乘information.I想我必須這樣做pro​​gramatically.It看起來不是很複雜,但我想如果我可以從暗號查詢本身得到它。