Cypher 기본 문법
그래프를 읽고, 만들고, 수정하고, 삭제하는 Cypher의 핵심 문법을 익힙니다.
Cypher의 모든 쿼리는 "패턴"을 기반으로 합니다.
그래프에서 특정 패턴을 찾고, 그 결과를 반환하는 구조입니다.
MATCH // 어떤 패턴을 찾을 것인가 WHERE // 조건은 무엇인가 RETURN // 무엇을 반환할 것인가
패턴 표현법
Cypher에서 그래프 패턴은 ASCII 아트처럼 직관적입니다.
(n) → 노드
(n:Person) → Person 라벨을 가진 노드
(n)-[r]->(m) → n에서 m으로의 관계
(n)-[:KNOWS]->(m) → KNOWS 타입의 관계
그래프 그림을 그대로 코드로 옮기는 느낌입니다.
핵심 규칙
노드는 ( ) 소괄호로 감싸고,
관계는 -[ ]-> 대괄호 + 화살표로 표현합니다.
라벨은 :이름 콜론으로 시작하고,
변수는 괄호 안에 이름을 넣습니다: (p:Person)
가장 기본이 되는 읽기(Read) 쿼리입니다.
SQL의 SELECT ... FROM ... WHERE에 해당합니다.
MATCH READ
그래프에서 특정 패턴과 일치하는 데이터를 찾습니다.
MATCH (p:Person) RETURN p
MATCH (p:Person) WHERE p.name = "홍길동" RETURN p
// 홍길동이 본 영화 찾기 MATCH (p:Person {name: "홍길동"})-[:WATCHED]->(m:Movie) RETURN m.title, m.year
WHERE의 다양한 조건
WHERE p.age > 25 → 숫자 비교
WHERE p.name STARTS WITH "홍" → 문자열 시작
WHERE p.name CONTAINS "길" → 문자열 포함
WHERE p.age IN [25, 30, 35] → 목록 포함 여부
WHERE p.name IS NOT NULL → 속성 존재 여부
WHERE p.age > 20 AND p.age < 40 → 복합 조건
RETURN 활용법
RETURN p → 노드 전체 반환
RETURN p.name, p.age → 특정 속성만 반환
RETURN p.name AS 이름 → 별칭(alias) 지정
RETURN DISTINCT p.name → 중복 제거
RETURN count(p) AS 인원수 → 집계 함수
WHERE 인라인 표기법
WHERE를 쓰지 않고 노드 안에 직접 조건을 넣을 수도 있습니다.
MATCH (p:Person {name: "홍길동"})
이것은 MATCH (p:Person) WHERE p.name = "홍길동"과 동일합니다.
단순한 동등 비교일 때 이 방식이 더 간결합니다.
그래프에 노드와 관계를 생성하는 쿼리입니다.
CREATE WRITE
새로운 노드나 관계를 무조건 생성합니다. 중복 검사 없음.
// Person 노드 하나 생성 CREATE (p:Person {name: "홍길동", age: 30}) RETURN p
CREATE (p:Person {name: "홍길동"})-[:WATCHED {rating: 4.5}]->(m:Movie {title: "인셉션"})
MERGE WRITE
"있으면 찾고, 없으면 생성". 중복 방지에 핵심적인 명령어.
// 이미 있으면 기존 노드를 반환, 없으면 새로 생성 MERGE (p:Person {name: "홍길동"}) RETURN p
MERGE (p:Person {name: "홍길동"}) ON CREATE SET p.created = datetime() ON MATCH SET p.lastSeen = datetime() RETURN p
| 비교 | CREATE | MERGE |
|---|---|---|
| 동작 | 항상 새로 생성 | 있으면 찾기, 없으면 생성 |
| 중복 | 중복 노드 생길 수 있음 | 중복 방지 |
| 사용 시점 | 초기 데이터 일괄 삽입 빠르지만 중복 주의 |
데이터 업데이트·동기화 안전하지만 상대적으로 느림 |
실무 팁
데이터를 처음 넣을 때는 CREATE가 빠르고,
이후 업데이트하거나 외부 데이터를 반복 적재할 때는 MERGE가 안전합니다.
MERGE는 항상 "어떤 조건으로 찾을 것인가"를 명확히 해야 합니다.
조건이 모호하면 의도치 않은 중복이 생길 수 있습니다.
이미 존재하는 노드나 관계의 속성을 변경하는 쿼리입니다.
SET UPDATE
속성을 추가하거나 변경합니다.
MATCH (p:Person {name: "홍길동"}) SET p.age = 31 RETURN p
MATCH (p:Person {name: "홍길동"}) SET p.age = 31, p.city = "서울" RETURN p
// 기존 Person 노드에 Developer 라벨 추가 MATCH (p:Person {name: "홍길동"}) SET p:Developer RETURN p
REMOVE DELETE
속성이나 라벨을 제거합니다.
MATCH (p:Person {name: "홍길동"}) REMOVE p.city RETURN p
MATCH (p:Person:Developer {name: "홍길동"}) REMOVE p:Developer RETURN p
SET vs REMOVE 정리
SET: 속성 추가/변경, 라벨 추가
REMOVE: 속성 삭제, 라벨 삭제
노드나 관계 자체를 삭제하는 것은 DELETE이고,
그 안의 속성/라벨만 지우는 것이 REMOVE입니다.
노드와 관계를 삭제하는 쿼리입니다.
DELETE DELETE
노드나 관계를 삭제합니다. 단, 관계가 있는 노드는 삭제 불가.
// 홍길동과 인셉션 사이의 WATCHED 관계만 삭제 MATCH (p:Person {name: "홍길동"})-[r:WATCHED]->(m:Movie) DELETE r
왜 관계가 있으면 노드를 삭제할 수 없는가?
그래프에서 관계는 반드시 시작 노드와 끝 노드가 있어야 합니다.
노드만 삭제하면 관계가 "허공에 떠있는" 상태가 되기 때문에
Neo4j는 이를 방지합니다.
해결 방법: DETACH DELETE를 사용하면
노드에 연결된 관계를 먼저 삭제한 뒤 노드를 삭제합니다.
DETACH DELETE DELETE
노드에 연결된 모든 관계를 함께 삭제합니다.
MATCH (p:Person {name: "홍길동"}) DETACH DELETE p
// 모든 노드와 관계를 삭제 — 학습용에서만 사용 MATCH (n) DETACH DELETE n
DELETE vs DETACH DELETE
DELETE: 관계만 삭제하거나, 관계가 없는 노드 삭제
DETACH DELETE: 노드 + 연결된 관계 모두 삭제
실무에서 노드를 삭제할 때는 거의 항상 DETACH DELETE를 사용합니다.
| 명령어 | 유형 | 설명 | 예시 |
|---|---|---|---|
| MATCH | 읽기 | 패턴에 맞는 데이터 찾기 | MATCH (n:Person) |
| WHERE | 필터 | 조건으로 결과 필터링 | WHERE n.age > 25 |
| RETURN | 반환 | 결과 출력 | RETURN n.name |
| CREATE | 생성 | 무조건 새로 생성 | CREATE (n:Person {...}) |
| MERGE | 생성 | 있으면 찾기, 없으면 생성 | MERGE (n:Person {...}) |
| SET | 수정 | 속성 추가/변경, 라벨 추가 | SET n.age = 31 |
| REMOVE | 수정 | 속성 삭제, 라벨 삭제 | REMOVE n.city |
| DELETE | 삭제 | 관계 또는 독립 노드 삭제 | DELETE r |
| DETACH DELETE | 삭제 | 노드 + 연결 관계 모두 삭제 | DETACH DELETE n |
이 9개 명령어가 Cypher의 핵심입니다.
읽기: MATCH → WHERE → RETURN
쓰기: CREATE / MERGE
수정: SET / REMOVE
삭제: DELETE / DETACH DELETE
이것만 알면 대부분의 그래프 작업이 가능합니다.