2017-05-24 2 views
0

neo4j의 절대적인 멍청한 질문이었고 이전 질문에 매우 관대 한 도움을 받았기 때문에 저는 여전히 고민 중이므로 다시 한 번 운을 시험해 볼 것이라고 생각했습니다.Neo4j의 전체 경로 수와 전체 경로 반환

예시 시나리오는 집에 들어가서 한 방에서 다른 방으로 걸어가는 학생의 시나리오입니다. 여행은 특정 방에서 시작하거나 끝낼 필요는 없지만 학생이 방에 들어가는 순서는 중요합니다.

내가 알고 싶은 것은 학생들이 찍은 모든 길을 문제의 길을 여러 번 찍은 횟수와 함께 나타냅니다. 아래는 샘플 데이터이며, 나는 (블로그 게시물의 시리즈와 함께 이전 질문의 대답 덕분에) 시도했다 :

파일이

학생의 노드를 만드는
ID|SID|EID|ROOM|ENTERS|LEAVES 
1|1|12|BLUE|1/01/2015 11:00|4/01/2015 10:19 
2|2|18|GREEN|1/01/2015 12:11|1/01/2015 12:11 
3|2|18|YELLOW|1/01/2015 12:11|1/01/2015 12:20 
4|2|18|BLUE|1/01/2015 12:20|5/01/2015 10:48 
5|3|28|GREEN|1/01/2015 18:41|1/01/2015 18:41 
6|3|28|YELLOW|1/01/2015 18:41|1/01/2015 21:00 
7|3|28|BLUE|1/01/2015 21:00|9/01/2015 9:30 
8|4|36|BLUE|1/01/2015 19:30|3/01/2015 11:00 
9|5|40|GREEN|2/01/2015 19:08|2/01/2015 19:08 
10|5|40|ORANGE|2/01/2015 19:08|3/01/2015 2:43 
11|5|40|PURPLE|3/01/2015 2:43|4/01/2015 16:44 
12|6|48|GREEN|3/01/2015 11:52|3/01/2015 11:52 
13|6|48|YELLOW|3/01/2015 11:52|3/01/2015 17:45 
14|6|48|RED|3/01/2015 17:45|7/01/2015 10:00 

을 dorm.csv을, 방문이 고유 PREV 관계를 만들기 ID 속성

CREATE CONSTRAINT ON (student:Student) ASSERT student.studentID IS UNIQUE; 
CREATE CONSTRAINT ON (room:Room) ASSERT room.roomID IS UNIQUE; 
CREATE CONSTRAINT ON (visit:Visit) ASSERT visit.visitID IS UNIQUE; 


USING PERIODIC COMMIT 
LOAD CSV WITH HEADERS FROM "file:///dorm.csv" as line fieldterminator '|' 
MERGE (student:Student {studentID: line.SID}) 
MERGE (room:Room {roomID: line.ROOM}) 
MERGE (visit:Visit {visitID: line.ID, roomID: line.ROOM, studentID: line.SID, ticketID: line.EID}) 
create (student)-[:VERB]->(visit)-[:OBJECT]->(room) 

에 의해 식별되는 방에 들어가는 학생의 이벤트 룸 및 방문 순서 또는 학생에 이동하는 순서가.이 파일 dormprev에서 데이터를 사용 할 수 있습니다. CSV. 학생이 한 방만 방문한 경우이 ID는 Dormprev 파일에 나타나지 않습니다. 목적은 링크/체인 방문입니다.

ID|PREV_ID|EID 
3|2|18 
4|3|18 
6|5|28 
7|6|28 
10|9|40 
11|10|40 
13|12|48 
14|13|48 

USING PERIODIC COMMIT 
LOAD CSV WITH HEADERS FROM "file:///dormprev.csv" as line fieldterminator '|' 
MATCH (new:Visit {visitID: line.ID}) 
MATCH (old:Visit {visitID: line.PREV_ID}) 
MERGE (new)-[:PREV]->(old) 

아래와 같이 데이터 I 그러나 아래의 쿼리

MATCH (student:Student)-[:VERB]->(visit:Visit)-[:OBJECT]-(room:Room) 
RETURN student, visit, room 

모든 학생들의 여행을 볼 수 있습니다, 나는 어떻게 전체 경로의 객실을 반환하는 아무 생각이 없습니다.

나는이 쿼리를 실행하면

MATCH p = (:Visit)<-[:PREV]-(:Visit) return p 

내가, 예를 들어, 학생 ID 별도의 쌍으로이 개 반환 녹색과 노란색 후, 노랑, 파랑에 대한 것을 볼 수 있습니다 - 내가 그린 같은 것을 보려는 그 SENS를 만드는 경우

MATCH p = (:Visit)<-[:PREV]-(:Visit) 
WITH p, EXTRACT(v IN NODES(p) | v.roomID) AS rooms 
UNWIND rooms AS stays 
WITH p, COUNT(DISTINCT stays) AS distinct_stays 
WHERE distinct_stays = LENGTH(NODES(p)) 
RETURN EXTRACT(v in NODES(p) | v.roomID), count(p) 
ORDER BY count(p) DESC 

는 오히려 "전체 경로"의 수보다 그 짝의 수를 반환합니다, 노랑, 파랑

이 또한 내가 아래 쿼리를 실행하면 것을 의미한다 이자형.

예를 들어 SID 2와 SID 3 모두 GREEN, YELLOW, BLUE 순으로 방문합니다. SID 5는 GREEN, ORANGE, PURPLE 순으로 방문합니다.

내가보고 희망하고있다 :

[GREEN, YELLOW, BLUE] 2 
[GREEN, ORANGE, PURPLE] 1 

등은 위의 모델이 가능 그래서 누군가가 도와주세요 수 있다면 올바른 방향으로 날 지점? 방문한 객실의 수는 보장되지 않으며 1에서 *까지 가능합니다. 그러나 한 방만 방문하면 관심이 없으므로이 모델이 이해할만한 것으로 생각되는 이유가 있습니다 (다시 블로그 게시물 시리즈에서 도난 당함).

위의 내용이 의미가 있지만 도움이 될만한지 모르겠다. 훌륭한 사용 사례로 유용하며 유용 할 것입니다.

친절한 도움에 감사드립니다.

답변

0

당신이 찾고있는 것이 가변 경로 길이입니다. 그리고 쿼리 (별표 참고)에서이를 변경하면됩니다.

MATCH p = (:Visit)<-[:PREV*]-(:Visit) 

나에게 몇 가지 더 이상 언급 해주십시오. 네, 방문 노드에 roomID와 studentID가있는 편리함을 이해합니다 (이 특정 검색어를 훨씬 간단하게 유지함). 그러나 처음부터 관계를 갖는 모든 점을 무시하고 있습니다 (사실, 이렇게하면 현재 Student and Room 노드를 사용하는 데는 아무런 문제가 없습니다.) 당신은 그들을 유지 보수하는 데 어려움을 겪을 것입니다.

CREATE (student)-[:VERB]->(visit)<-[:OBJECT]-(room) 

기타 : 우리가 다음 방문의 관계가 실제로 다음과 같이 작성해야 속담 제 3 정규형 머리카락을 ;-), 분할 될 위하여려고하는 경우에 두 번째 (관계의 방향을주의) 완전히 노드를 방문하여 만들기 :보다 난 당신이 다른 모델 페지 고려해 볼 수 있습니다 당신은 매우 빠른 :-)이 도움이

희망, 톰

+0

감사합니다! 관계의 요점에 대해 만들어야 할 농담이 있습니다. 저는 제멋대로로 현저한 억제력을 보여주고 있습니다 ;-) 나는 그 순간에 뭔가 다른 것을 추적해야했지만 주말에 이것을 보길 원합니다. 변수 경로 길이로 쿼리를 변경하는 것과 관련하여 문제가 거의 해결 될 것이라고 생각하지만 하위 경로는 포함하지 않을 것입니다. 반면 "완전한"여행에만 관심이 있습니까? 즉, GYB 대신 [{G, Y}, {Y, B}, {GYB}]라는 쿼리를 사용하면 실제로 G Y B가 세 번 계산됩니다. 감사합니다. 월요일에 다시 게시 할 예정입니다. – c95mbq

+0

예, 분명히 "관계의 핵심"입니다 :-). 어쨌든 시작 지점에 들어오는 [: PREV]가없고 끝 지점에 나가는 [: PREV]가 없도록 몇 가지 추가 요구 사항을 추가 할 수 있습니다. 그렇게하면 완전한 여행 만 할 수 있습니다. –

+0

나는 물건을 바꾸고 결국 PREV 대신 NEXT를 만들었다. 내가 건너 왔던 다른 SO 게시물과 함께 귀하의 의견은 작은 샘플 데이터로 예상 결과를 반환하는 것으로 보이는 아래의 쿼리 결과를 얻었습니다. 'MATCH p = (from : Visit) - [: NEXT *] - > (방문 : 방문) WITH p, EXTRACT (v IN NODES p) | v.roomID) AS 객실 UNWIND 객실은 그대로 유지됩니다. WITH P, COUNT (DISTINCT 숙박) AS distinct_stays WHERE distinct_stays = LENGTH (NODES (p)) RETURN EXTRACT (v의 NODES (p) | v.roomID)), count (p)' 여러분의 모든 도움에 감사드립니다! – c95mbq

0

톰의 제안에 약간의 구축을 이동하고 말을해야 다음과 같이 조금 더 집중된 관계 유형 :

(:Student)-[:VISITED]->(:Room) 

방문한 순서대로 관계 (및 해당 객실 : 객실)를 주문할 수있는 : VISITED 관계에 입력 및 왼쪽 속성을 설정할 수 있습니다.

날짜 문자열에서 타임 스탬프를 파싱하려면 APOC Procedures (Neo4j 버전에 해당하는 올바른 버전을 설치해야 함)을 사용하는 대신 가져올 항목이 있습니다.

USING PERIODIC COMMIT 
LOAD CSV WITH HEADERS FROM "file:///dorm.csv" as line fieldterminator '|' 
MERGE (student:Student {studentID: line.SID}) 
MERGE (room:Room {roomID: line.ROOM}) 
WITH student, room, apoc.date.parse(line.ENTERS, 'ms', 'MM/dd/yyyy HH:mm') as entered, apoc.date.parse(line.LEAVES, 'ms', 'MM/dd/yyyy HH:mm') as left 
CREATE (student)-[r:VISITED]->(room) 
SET r.entered = entered, r.left = left 

그리고 모든 경로와 그 경로를 촬영 한 학생의 수를 얻기 위해 지금 쿼리는 매우 간단하게 : 톰, 많은 감사 힙

MATCH (s:Student)-[v:VISITED]->(r:Room) 
WHERE size((s)-[:VISITED]->()) > 1 
WITH s, r 
ORDER BY v.entered ASC 
WITH s, collect(r.roomID) as rooms 
RETURN rooms, count(s) 
+0

도움을 주셔서 감사합니다 InverseFalcon, 많이 감사하겠습니다.나는 이것을 아직 시험 할 기회가 없었지만 앞으로 며칠 내에 그렇게하기를 희망하고 다시 게시 할 것이다. 너와 톰의 도움은 나 자신과 같은 멍청한 놈에게는 믿기지 않을 정도로 중요하다. 오래 동안 SQL로 작업 해 왔지만, 저는이 문제를두고 머리를 쓰려고 고심하고 있습니다. 전구를 기다리고 기다리고 있습니다. 지속될 가치가있는 부인할 수없는 가치로 보입니다. 친절하고 관대 한 도움이 먼 길을 간다. 내가이 일로 돌아갈 기회를 얻 자마자 다시 게시 할 것입니다. 환호 – c95mbq

+0

도와 드리겠습니다! 추가 리소스와 조언을 원하면 [neo4j-users slack] (https://neo4j.com/developer/slack/)을 고려해보십시오. 또한 neo4j 브라우저 자체를 통해 제공되는 내장 자습서 중 일부를 반드시 수행해야합니다.이 자습서는 매우 풍부합니다. – InverseFalcon

+0

감사합니다 InverseFalcon. 나는 여유분에 등록했으며, 큰 도움이 될 것이라고 확신합니다. 나는 당신의 질의를 테스트 할 수 없었기 때문에 잘못된 버전의 apoc을 얻었지만, 일이 조금씩 사라질 때 확실히 재검토를하고 있다고 생각합니다. 당신이나 톰의 대답을 받아들이든지 톰과 같이 갔는지, 둘 다 선택할 수 있으면 좋겠다. 모든 도움을 주셔서 감사합니다. 다시 말하지만 상황이 더 조용 해지면 apoc과 솔루션을 다시 살펴 보겠습니다. 건배 – c95mbq