45

Cypher 기초: 제조 데이터 생성과 조회

Neo4j & Cypher

학습 목표

CREATE로 설비/부품/고장 노드를 생성한다 MATCH로 패턴 기반 조회를 수행한다 WHERE, RETURN, ORDER BY를 활용한다 SET, DELETE로 데이터를 수정/삭제한다

Cypher 기초: 제조 데이터로 배우는 그래프 쿼리

Cypher = "ASCII Art 같은 쿼리 언어"

[Cypher의 핵심 아이디어]

노드:  ( )     괄호로 표현
관계:  -[ ]->  화살표로 표현
패턴:  (a)-[r]->(b)  노드-관계-노드

SQL이 "테이블과 조인"을 다루듯,
Cypher는 "노드와 관계"를 다룹니다.

1. CREATE - 노드 생성

// 설비 노드 생성
CREATE (e:Equipment {
  name: "CNC밀링 3호기",
  model: "VMC-850",
  manufacturer: "화천기계",
  installDate: date("2021-06-15"),
  status: "운전중",
  operatingHours: 12450,
  location: "A동 2라인 3번"
})
RETURN e;

// 부품 노드 생성
CREATE (p:Part {
  partNumber: "BRG-6205-2RS",
  name: "메인 베어링",
  manufacturer: "NSK",
  lifespan: 8000,
  currentHours: 6500,
  cost: 45000
})
RETURN p;

// 고장 노드 생성
CREATE (f:Fault {
  alarmCode: "E-201",
  name: "스핀들 과열",
  severity: "중요",
  description: "스핀들 온도가 설정값(80도) 초과",
  avgDowntime: 45
})
RETURN f;

여러 노드 한번에 생성

// 루트브릭스 공장 기본 구조 생성
CREATE
  // 공장
  (factory:Factory {name: "루트브릭스 김포 공장", location: "경기도 김포시"}),

  // 생산 라인
  (lineA2:ProductionLine {name: "A동 2라인", lineNumber: "A-2", capacity: 500}),

  // 설비
  (mill3:Equipment {name: "CNC밀링 3호기", model: "VMC-850",
                    manufacturer: "화천기계", status: "운전중",
                    operatingHours: 12450}),
  (lathe1:Equipment {name: "CNC선반 1호기", model: "LX-500",
                     manufacturer: "화천기계", status: "운전중",
                     operatingHours: 18200}),

  // 구성요소
  (spindleUnit:Component {name: "스핀들 유닛", componentType: "주축"}),
  (feedSystem:Component {name: "이송계", componentType: "이송"}),

  // 부품
  (bearing:Part {name: "메인 베어링", partNumber: "BRG-6205-2RS",
                 manufacturer: "NSK", lifespan: 8000, currentHours: 6500}),
  (spindleMotor:Part {name: "스핀들 모터", partNumber: "MOT-SP-15KW",
                      manufacturer: "화낙", lifespan: 20000, currentHours: 12450}),
  (coolant:Part {name: "냉각 시스템", partNumber: "COOL-SYS-850",
                 manufacturer: "화천기계", lifespan: 15000, currentHours: 12450}),
  (ballscrew:Part {name: "볼스크류(X축)", partNumber: "BS-3210-X",
                   manufacturer: "THK", lifespan: 12000, currentHours: 12450}),

  // 고장
  (alarmE201:Fault {alarmCode: "E-201", name: "스핀들 과열",
                    severity: "중요", avgDowntime: 45}),
  (alarmE305:Fault {alarmCode: "E-305", name: "이송 축 위치 오차",
                    severity: "경고", avgDowntime: 30}),

  // 근본 원인
  (causeCoolant:RootCause {name: "냉각수 부족", category: "소모품", probability: 0.45}),
  (causeBearing:RootCause {name: "베어링 마모", category: "기계적 마모", probability: 0.35}),
  (causeOvercut:RootCause {name: "과절삭", category: "가공 조건", probability: 0.20}),
  (causeBacklash:RootCause {name: "볼스크류 백래시", category: "기계적 마모", probability: 0.60}),

  // 정비 조치
  (actionRefill:MaintenanceAction {name: "냉각수 보충", difficulty: "쉬움",
                                   estimatedTime: 15}),
  (actionBearing:MaintenanceAction {name: "베어링 교체", difficulty: "어려움",
                                    estimatedTime: 240}),
  (actionCutting:MaintenanceAction {name: "절삭 조건 수정", difficulty: "보통",
                                    estimatedTime: 30}),
  (actionBallscrew:MaintenanceAction {name: "볼스크류 백래시 보정", difficulty: "어려움",
                                      estimatedTime: 120}),

  // 작업자
  (workerKim:Worker {name: "김기술", employeeId: "EMP-001", experience: 15}),
  (workerLee:Worker {name: "이신입", employeeId: "EMP-042", experience: 1}),

  // 스킬
  (skillBasic:Skill {name: "기본 정비", level: "초급"}),
  (skillCNC:Skill {name: "CNC 프로그래밍", level: "중급"}),
  (skillSpindle:Skill {name: "스핀들 정비", level: "고급"}),
  (skillPrecision:Skill {name: "정밀 정비", level: "고급"}),

  // === 관계 생성 ===
  // 공장 구조
  (factory)-[:HAS_LINE]->(lineA2),
  (lineA2)-[:HAS_EQUIPMENT]->(mill3),
  (lineA2)-[:HAS_EQUIPMENT]->(lathe1),

  // 설비-구성요소-부품
  (mill3)-[:HAS_COMPONENT]->(spindleUnit),
  (mill3)-[:HAS_COMPONENT]->(feedSystem),
  (spindleUnit)-[:HAS_PART]->(bearing),
  (spindleUnit)-[:HAS_PART]->(spindleMotor),
  (spindleUnit)-[:HAS_PART]->(coolant),
  (feedSystem)-[:HAS_PART]->(ballscrew),

  // 부품-고장 연관
  (bearing)-[:CAN_CAUSE]->(alarmE201),
  (coolant)-[:CAN_CAUSE]->(alarmE201),
  (ballscrew)-[:CAN_CAUSE]->(alarmE305),

  // 고장-원인
  (alarmE201)-[:CAUSED_BY]->(causeCoolant),
  (alarmE201)-[:CAUSED_BY]->(causeBearing),
  (alarmE201)-[:CAUSED_BY]->(causeOvercut),
  (alarmE305)-[:CAUSED_BY]->(causeBacklash),

  // 원인-조치
  (causeCoolant)-[:RESOLVED_BY]->(actionRefill),
  (causeBearing)-[:RESOLVED_BY]->(actionBearing),
  (causeOvercut)-[:RESOLVED_BY]->(actionCutting),
  (causeBacklash)-[:RESOLVED_BY]->(actionBallscrew),

  // 작업자-설비
  (workerKim)-[:OPERATES]->(mill3),
  (workerLee)-[:OPERATES]->(lathe1),

  // 작업자-스킬
  (workerKim)-[:HAS_SKILL]->(skillBasic),
  (workerKim)-[:HAS_SKILL]->(skillCNC),
  (workerKim)-[:HAS_SKILL]->(skillSpindle),
  (workerLee)-[:HAS_SKILL]->(skillBasic),

  // 조치-필요스킬
  (actionRefill)-[:REQUIRES_SKILL]->(skillBasic),
  (actionBearing)-[:REQUIRES_SKILL]->(skillSpindle),
  (actionCutting)-[:REQUIRES_SKILL]->(skillCNC),
  (actionBallscrew)-[:REQUIRES_SKILL]->(skillPrecision);

2. MATCH - 패턴 조회

// 모든 설비 조회
MATCH (e:Equipment)
RETURN e.name, e.model, e.status, e.operatingHours
ORDER BY e.operatingHours DESC;

// 특정 설비의 부품 목록
MATCH (e:Equipment {name: "CNC밀링 3호기"})
      -[:HAS_COMPONENT]->(c:Component)
      -[:HAS_PART]->(p:Part)
RETURN c.name AS 구성요소, p.name AS 부품, p.manufacturer AS 제조사,
       p.currentHours + "/" + p.lifespan AS 사용시간_수명;

// 알람 E-201의 원인과 조치
MATCH (f:Fault {alarmCode: "E-201"})
      -[:CAUSED_BY]->(cause:RootCause)
      -[:RESOLVED_BY]->(action:MaintenanceAction)
RETURN cause.name AS 원인,
       cause.probability AS 확률,
       action.name AS 조치,
       action.difficulty AS 난이도,
       action.estimatedTime + "분" AS 예상시간
ORDER BY cause.probability DESC;

3. 고급 패턴 매칭

// 수명 80% 이상 사용된 부품 (교체 예정)
MATCH (e:Equipment)-[:HAS_COMPONENT]->()-[:HAS_PART]->(p:Part)
WHERE toFloat(p.currentHours) / p.lifespan > 0.8
RETURN e.name AS 설비, p.name AS 부품,
       p.currentHours AS 현재시간, p.lifespan AS 수명,
       round(toFloat(p.currentHours) / p.lifespan * 100, 1) + "%" AS 사용률
ORDER BY toFloat(p.currentHours) / p.lifespan DESC;

// 특정 작업자가 수행 가능한 정비 조치
MATCH (w:Worker {name: "이신입"})-[:HAS_SKILL]->(s:Skill)
      <-[:REQUIRES_SKILL]-(a:MaintenanceAction)
RETURN a.name AS 수행가능조치, a.difficulty AS 난이도,
       s.name AS 보유스킬;

// 작업자별 대응 불가능한 고장 파악
MATCH (f:Fault)-[:CAUSED_BY]->()-[:RESOLVED_BY]->(a:MaintenanceAction)
      -[:REQUIRES_SKILL]->(s:Skill)
WHERE NOT EXISTS {
  MATCH (w:Worker {name: "이신입"})-[:HAS_SKILL]->(s)
}
RETURN DISTINCT f.name AS 대응불가_고장, s.name AS 필요스킬;

4. SET & DELETE - 수정과 삭제

// 설비 상태 변경
MATCH (e:Equipment {name: "CNC밀링 3호기"})
SET e.status = "정비중", e.lastMaintenance = datetime()
RETURN e.name, e.status;

// 운전 시간 업데이트
MATCH (e:Equipment {name: "CNC밀링 3호기"})
SET e.operatingHours = e.operatingHours + 8
RETURN e.name, e.operatingHours;

// 관계 삭제 (노드는 유지)
MATCH (w:Worker {name: "이신입"})-[r:OPERATES]->(e:Equipment)
DELETE r;

// 노드와 관계 모두 삭제
MATCH (n:Skill {name: "임시스킬"})
DETACH DELETE n;

// ⚠️ 전체 데이터 삭제 (주의!)
// MATCH (n) DETACH DELETE n;

5. MERGE - 중복 없이 생성

// 없으면 생성, 있으면 업데이트
MERGE (e:Equipment {name: "CNC밀링 3호기"})
ON CREATE SET e.status = "신규", e.createdAt = datetime()
ON MATCH SET e.lastChecked = datetime()
RETURN e;

// 관계도 MERGE 가능
MATCH (w:Worker {name: "이신입"})
MATCH (e:Equipment {name: "CNC밀링 3호기"})
MERGE (w)-[:OPERATES]->(e);

SQL vs Cypher 비교

작업SQLCypher
전체 조회SELECT * FROM equipmentMATCH (e:Equipment) RETURN e
조건 조회WHERE status = '운전중'WHERE e.status = "운전중"
조인 (1단계)JOIN parts ON ...-[:HAS_PART]->
조인 (3단계)JOIN x3 (복잡!)-[:REL*3]-> (간단!)
경로 탐색불가능 (재귀 CTE 필요)-[:REL*1..5]->
생성INSERT INTOCREATE/MERGE
수정UPDATE ... SETSET
삭제DELETE FROMDELETE/DETACH DELETE

🚀 설치 없이 지금 바로 연습하기

Neo4j를 아직 안 깔았어도 괜찮습니다. AX Academy 내장 Cypher 샌드박스가 있어요.

👉 Cypher Playground 시뮬레이터 열기

  • 가입·설치 0 — 브라우저에서 바로 MATCH/CREATE/MERGE 실행
  • 제조 도메인 샘플 그래프(Equipment·Worker·Process) 프리로드 → 위 쿼리를 그대로 복붙해 결과를 그래프로 확인
  • 위 5개 절(CREATE/MATCH/SET·DELETE/MERGE)을 손에 익히는 용도

단, 내장 샌드박스는 학습용 간이 엔진입니다. 인덱스·대용량·Python 연동 등 본 프로젝트 작업은 실제 Neo4j(Docker/Aura) 로 진행하세요.

AI로 학습하기 — 꿀팁
🧪설비-부품-고장 Cypher 패턴 심화AI 학습 팁

CREATE와 MATCH의 기초 패턴을 제조 설비-부품-고장 관계에 적용한 실습 쿼리를 AI에게 요청하세요.

Neo4j Cypher로 제조 데이터를 다루는 연습 문제 5개를 만들어줘. 조건: (1) Equipment→HAS_PART→Component→CAUSED→Failure 구조, (2) CREATE로 설비/부품/고장 노드 생성, (3) MATCH+WHERE로 특정 설비의 고장 이력 조회, (4) 각 문제에 정답 Cypher와 예상 결과도 포함.
이 팁이 도움이 됐나요?
핵심 포인트
  • Cypher 기본: (노드)-[:관계]->(노드) 패턴으로 조회
  • CREATE로 노드/관계 생성, MATCH로 패턴 조회
  • 가변 길이 관계 탐색(*1..5)이 SQL 대비 압도적으로 간편
  • MERGE는 중복 생성 방지에 유용