Cypher Query Language
정의
Neo4j 그래프 데이터베이스에서 사용하는 그래프 쿼리 언어. SQL의 선언적 문법을 그래프 구조에 맞게 재설계하여, 노드와 관계를 직관적으로 조회할 수 있도록 만들었다.
기본 문법
MATCH: 데이터 조회
MATCH (movie:Movie)
RETURN movie.title(movie:Movie): Movie 라벨의 노드를 movie 변수에 바인딩- RETURN: 반환할 값 명시
노드 조회
MATCH (m:Movie)
WHERE m.year = 2024
RETURN m.title, m.rating
LIMIT 10관계 조회
MATCH (user:User)-[rated:RATED]->(movie:Movie)
WHERE rated.rating > 4
RETURN user.name, movie.title, rated.rating-[rated:RATED]->: RATED 관계를 따라 조회 (방향성)<-: 역방향 관계
다중 홉 (Multi-hop) 조회
MATCH (actor:Actor)-[acted:ACTED_IN]->(movie:Movie)
-[belongs:BELONGS_TO]->(genre:Genre)
WHERE actor.name = "Tom Hanks"
RETURN movie.title, genre.name주요 절 (Clauses)
| 절 | 설명 | 예 |
|---|---|---|
| MATCH | 패턴 매칭 | MATCH (n:Person) |
| WHERE | 조건 필터링 | WHERE n.age > 30 |
| RETURN | 결과 반환 | RETURN n.name, n.age |
| ORDER BY | 정렬 | ORDER BY n.age DESC |
| LIMIT | 결과 개수 제한 | LIMIT 10 |
| SKIP | 건너뛰기 | SKIP 5 |
| DISTINCT | 중복 제거 | RETURN DISTINCT n.category |
CREATE: 데이터 생성
CREATE (movie:Movie {title: "Toy Story", year: 1995})
RETURN movie관계 생성
MATCH (actor:Actor {name: "Tom Hanks"}),
(movie:Movie {title: "Forrest Gump"})
CREATE (actor)-[acted:ACTED_IN {role: "Forrest Gump"}]->(movie)
RETURN actedUPDATE: 데이터 수정
MATCH (movie:Movie {title: "Toy Story"})
SET movie.rating = 4.5, movie.year = 1996
RETURN movieDELETE: 데이터 삭제
MATCH (movie:Movie {title: "To Delete"})
DELETE movie함수와 연산
문자열 함수
MATCH (m:Movie)
WHERE m.title CONTAINS "Toy"
RETURN m숫자 함수
MATCH (user:User)-[rated:RATED]->(movie:Movie)
RETURN movie.title, avg(rated.rating) AS avg_rating경로 함수
MATCH path = (actor:Actor)-[*1..3]->(movie:Movie)
WHERE actor.name = "Tom Hanks"
RETURN length(path) AS hops, path실제 예제
예제 1: 영화 줄거리로 유사 영화 찾기
MATCH (m1:Movie {title: "Toy Story"}),
(m2:Movie)-[rel:SIMILAR_TO]->(m1)
RETURN m2.title, m2.plot
ORDER BY rel.similarity_score DESC
LIMIT 5예제 2: 사용자가 본 영화와 유사한 영화 추천
MATCH (user:User {id: 123})-[rated:RATED]->(movie:Movie),
(movie)-[similar:SIMILAR_TO]->(similar_movie:Movie)
WHERE rated.rating > 4
RETURN similar_movie.title, avg(similar.similarity_score) AS avg_similarity
ORDER BY avg_similarity DESC
LIMIT 10예제 3: 배우 간 협업도 계산
MATCH (actor1:Actor)-[:ACTED_IN]->(movie:Movie)<-[:ACTED_IN]-(actor2:Actor)
WHERE actor1.name = "Tom Hanks"
RETURN actor2.name, count(*) AS movies_together
ORDER BY movies_together DESCCypher vs. SQL
| 항목 | SQL | Cypher |
|---|---|---|
| JOIN | 필수 (성능 저하↑) | 관계 따라가기 (일정 성능) |
| 복잡도 | 다중 JOIN 시 복잡 | 직관적 문법 |
| 그래프 표현 | 어려움 | 자연스러움 |
| 가독성 | 테이블 기준 | 그래프 구조 반영 |
온톨로지 설계에서의 활용
1. 클래스 계층 조회
MATCH (subclass:Class)-[:SUBCLASS_OF*0..]->(superclass:Class)
WHERE superclass.name = "Product"
RETURN subclass.name2. 프로퍼티와 도메인 확인
MATCH (prop:Property)-[:DOMAIN]->(class:Class)
RETURN class.name, collect(prop.name) AS properties3. 인스턴스 범주화
MATCH (instance:Instance {id: "prod_001"})-[:INSTANCE_OF]->(class:Class)
RETURN class.name4. 관계 기반 쿼리
MATCH (product:Product)-[:BELONGS_TO]->(category:Category),
(product)-[:HAS_PROPERTY]->(prop:Property)
WHERE category.name = "Electronics"
RETURN product.name, collect(prop.name) AS propertiesVector INDEX와의 통합
CALL db.index.vector.queryNodes('movie_plot_embedding', 10, query_vector)
YIELD node AS movie, score
RETURN movie.title, movie.plot, score
ORDER BY score DESC성능 최적화
✅ 인덱스 활용: CREATE INDEX ON (n:Label) FOR (n.property)
✅ LIMIT 활용: 불필요한 결과 제한
✅ WHERE 조건 최대한 앞에: 조기 필터링
✅ 관계 방향 명시: 순방향/역방향 구분
관련 개념: Graph Database, Vector Retriever, Graph RAG