2

경로형 질의

Cypher 로 답하는 CQ

학습 목표
  • 3-hop 이상 경로 질의를 읽고 쓴다
  • 패턴 가독성이 왜 유지보수성인지 이해한다

계층 3: 경로형 (3-hop 이상) — 그래프의 홈그라운드

지연 전파(AN-02)를 봅시다. "기항 P의 지연이 영향을 주는 후속 화물과 화주는?"

관계형 DB라면 기항→하역이벤트→컨테이너→B/L→화주의 5중 조인에, 환적이면 컨테이너→2차 기항으로 재귀가 붙습니다. Cypher는 이것을 패턴 하나로 말합니다.

// AN-02: 특정 기항 지연의 영향 경로 (화주까지)
MATCH (pc:PortCall {callId: $delayedCall})
MATCH (pc)<-[:PART_OF_CALL]-(:DischargeEvent)-[:HANDLES]->(c:Container)
MATCH (c)-[:CONTAINS]->(:Cargo)<-[:COVERS]-(bl:BillOfLading)-[:CONSIGNEE]->(owner:CargoOwner)
OPTIONAL MATCH (c)<-[:HANDLES]-(:LoadingEvent)-[:PART_OF_CALL]->(next:PortCall)
WHERE next.callId <> pc.callId                    // 환적 연결분
RETURN owner.name, count(DISTINCT c) AS affectedBoxes,
       collect(DISTINCT next.callId)[..3] AS onwardCalls
ORDER BY affectedBoxes DESC;

패턴의 가독성이 곧 유지보수성입니다

화살표를 소리 내어 읽으면 업무 문장이 됩니다 — "기항에서 양하된 컨테이너에 담긴 화물을 커버하는 B/L의 수하인". SQL 5중 조인은 이렇게 읽히지 않습니다.

코스 1과 코스 2에서 예고한 **"4단계 이상이면 그래프"**의 실체가 이 쿼리입니다. 여섯 달 뒤 이 쿼리를 다시 열었을 때 무엇을 하는지 알아볼 수 있는가 — 그것이 유지보수 비용을 결정합니다.

환적 연결 위험

// AN-04: 환적 연결 실패 위험 — 양하 실적과 2차 모선 마감의 시간 차
MATCH (ts:TransshipmentEvent)-[:FROM_VESSEL]->(:Vessel),
      (ts)-[:TO_VESSEL]->(mv:Vessel)-[:MAKES_CALL]->(next:PortCall)
MATCH (ts)-[:HANDLES]->(c:Container)
WITH c, ts, next,
     duration.between(ts.actualTime, next.cargoCutoff).hours AS remainHours
WHERE remainHours < $riskThreshold                 // 예: 12시간
RETURN c.containerNumber, next.callId, remainHours
ORDER BY remainHours;

코스 1 첫 모듈에서 "환적이 1급 개념이어야 한다"고 했던 이유가 여기서 값을 합니다. 환적을 관계로만 뒀다면 이 쿼리의 ts.actualTime을 쓸 자리가 없습니다.

용어