2014-12-27 2 views
3

제 질문은 버스 정류장을 나타내는 노드가 많은 그래프 하나가 있습니다. 노드간에 사용 가능한 버스와 같은 버스 정보를 어떻게 포함해야합니까?Neo4j 버스 경로 응용 프로그램 모델링

두 노드 사이의 모든 버스 정보와 두 정류장 사이의 관계 특성 표시 거리를 갖는 노드간에 버스 관계를 작성하려고합니다.

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

Like A ----------------------------------------- --------------> B ---------------------------------- -------------------------> C

그래서 버스 나 버스를 찾을 수 있습니다 (직접 경로가없는 경우). A에서 M에 도달 했습니까?

먼저 경로에서 (neo4j 쿼리), A에서 M에 도달하는 방법을 찾습니다.

는 ---------------------------------- 내 경로가

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

A는 말 -------> L -----------------------------------> N ---- ---------------------------------------> M

문제는 어떻게 M에 대한 직접 버스가 사용 가능한지 여부를 프로그래밍 방식으로 확인하거나 버스를 상호 교환하는 방법

위의 시나리오에 따르면 나는 13B 또는 100A 중 하나를 택하여 A에서 N까지 11A, N에서 M까지 갈 수 있습니다.

프로그래밍 방식으로해야합니다.

버스 정보와 함께 두 스테이션 사이의 가능한 모든 경로와 경로의 총 거리를 검색하려고합니다.

+0

당신이 거리 나 전송의 수를 최소화 하시겠습니까 : 거리를 얻으려면? –

+0

각 경로의 총 dstancce와 함께 버스 교환 정보와 함께 가능한 모든 경로를 가져오고 싶습니다. –

답변

8

귀하의 모델은 더 많은 그래픽이 필요합니다. 즉, 버스 정보가있는 중지 노드 간의 관계에 배열 속성이 있어야한다고 생각하지 않습니다. 오히려, 버스는 정지 지점을 나타내는 관계가있는 노드 자체 여야합니다.

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

를, 그것은 이전의 수를 최소화하는 일정을 쉽게 찾을 수 있고 모두를 반환 해당되는 경우 필요한 이전 정보. 예를 들어, D A에서 (이전의 #의 측면에서 짧은) 모든 짧은 여행 일정 : 모든 하나의 전송이

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() 기능으로 원하는 정보를 반환하십시오.

또 다른 예입니다. 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

감사합니다. Nicole, 이것이 내가 찾고있는 것입니다. 나는 stop 사이의 NEXT 관계에 distance 속성을 추가했습니다.이 쿼리를 사용하여 가능한 모든 길로부터 총 거리를 얻었습니다. 그러나 null을 반환합니다. 일치 p = allShortestPaths ((a) - [: STOPS_AT *] - (c)) RETURN EXTRACT (대문자/소문자 구분 없음) (거리에서 0, r 관계 있음) x : NOTIES (p) | 경우 x : 중지 후 '중지'+ x.name 때 x : 버스 그때 '버스'+ x.id ELSE ' (p) | distance + r.distance)를 거리로 사용합니다.이 쿼리가 내부적으로 어떻게 작동하는지 설명 할 수 있습니다. –

+1

나는 거리가 중요하다는 것을 깨닫지 못했습니다 - 당신이 질문을 포함하도록 편집 할 수 있습니까? 위 쿼리는'NEXT' 관계가 아닌'STOPS_AT' 관계에 매치 되었기 때문에 null을 반환합니다. –

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 . 

나는 열심히 내가 programatically.It가 매우 복잡한 보이지 않는 그것을 할 수 있다고 생각 다양한 지식 버스 교류를 얻기 위해 찾는 있어요,하지만 난 사이퍼 쿼리 자체에서 그것을 얻을 수 있다면 나는 생각했다.