MATCH 절

MATCH 절

그래프에서 특정 모양의 데이터를 찾는 가장 기본적인 방법은 MATCH 절이에요. 이 절에 노드·관계·프로퍼티를 섞은 패턴을 적어 주면, 데이터베이스가 그래프 구조를 탐색하며 해당 패턴에 맞는 결과를 가져와 줘요. 이 페이지에서는 노드 찾기, 관계 찾기, WHERE 술어, 파라미터, 경로 바인딩까지 MATCH의 핵심 사용법을 영화 그래프 예시로 함께 살펴볼게요.

출처: Neo4j Cypher Manual — MATCH

노드 찾기

MATCH 절은 복잡도가 다양한 노드 패턴을 지정해서 그래프에서 꺼내올 수 있어요.

라벨 없이 노드 하나만 적으면 그래프의 모든 노드를 돌려줘요.

MATCH (n)
RETURN n

특정 라벨만 찾고 싶으면 라벨을 붙이면 돼요. 모든 Movie 노드를 찾아 제목을 돌려주는 쿼리예요.

MATCH (movie:Movie)
RETURN movie.title

라벨 표현식으로 찾기

MATCH는 라벨 표현식도 지원해요. OR(|) 표현식으로 Movie 또는 Person 노드를 한 번에 매칭할 수 있어요.

MATCH (n:Movie|Person)
RETURN n.name AS name, n.title AS title

부정(!) 라벨 표현식으로 Movie 가 아닌 노드를 라벨별로 세어 볼 수도 있어요.

MATCH (n:!Movie)
RETURN labels(n) AS label, count(n) AS labelCount

관계 찾기

MATCH 절은 다양한 복잡도의 관계 패턴도 지정할 수 있어요. 다만 관계 패턴은 양쪽에 노드 패턴 없이 단독으로 쓰일 수는 없어요. 또 패턴 안에서 관계 하나는 기본적으로 한 번만 매칭되는데, REPEATABLE ELEMENTS를 쓰면 노드와 관계가 한 MATCH 결과에서 여러 번 나올 수 있게 우회할 수 있어요.

빈 관계 패턴

--를 쓰면 방향을 가리지 않고, 타입·프로퍼티 필터 없이 관계가 연결된 노드들을 매칭해요.

MATCH (:Person {name: 'Oliver Stone'})--(n)
RETURN n AS connectedNodes

방향 있는 관계 패턴

관계 방향은 --><-- 화살표로 나타내요. Oliver Stone 노드에서 나가는 관계로 연결된 모든 영화를 찾는 쿼리예요.

MATCH (:Person {name: 'Oliver Stone'})-->(movie:Movie)
RETURN movie.title AS movieTitle

관계 변수와 방향 없는 관계

패턴에 변수를 도입하면 관계의 프로퍼티로 필터링하거나 관계 자체를 돌려줄 수 있어요. 예를 들어 관계 타입을 알아내려면 이렇게 해요.

MATCH (:Person {name: 'Oliver Stone'})-[r]->()
RETURN type(r) AS relType

바인딩된 관계가 방향을 지정하지 않으면, Cypher는 그 관계를 양방향 모두로 매칭해요.

MATCH (a)-[:ACTED_IN {role: 'Bud Fox'}]-(b)
RETURN a, b

관계 타입으로 필터링

관계 패턴에서 타입 앞에 콜론(:)을 붙이면 해당 타입만 매칭해요. Movie를 향하는 ACTED_IN 관계의 출발 배우를 찾는 쿼리예요.

MATCH (:Movie {title: 'Wall Street'})<-[:ACTED_IN]-(actor:Person)
RETURN actor.name AS actor

OR(|) 기호로 여러 타입 중 하나와 매칭할 수도 있어요.

MATCH (:Movie {title: 'Wall Street'})<-[:ACTED_IN|DIRECTED]-(person:Person)
RETURN person.name AS person

관계는 타입을 정확히 하나만 가지므로 ()-[:A&B]→()는 어떤 관계도 매칭하지 못하는 점을 기억하세요.

관계 여러 개 찾기

하나의 그래프 패턴에 관계 패턴을 여러 개 넣을 수 있어요. Charlie Sheen이 출연한 영화를 감독한 감독을 찾는 쿼리예요.

MATCH (:Person {name: 'Charlie Sheen'})-[:ACTED_IN]->(movie:Movie)<-[:DIRECTED]-(director:Person)
RETURN movie.title AS movieTitle, director.name AS director

WHERE 술어로 필터링

MATCH는 보통 WHERE 부속 절과 함께 쓰여 패턴을 더 구체적으로 다듬어요. 이 술어들은 매칭이 끝난 뒤의 단순 필터가 아니라 패턴 자체의 일부로 취급되므로, WHERE 절은 대응하는 MATCH 절과 항상 함께 두는 게 좋아요.

MATCH (charlie:Person)-[:ACTED_IN]->(movie:Movie)
WHERE charlie.name = 'Charlie Sheen'
RETURN movie.title AS movieTitle

MATCH 절이 여러 개일 때는 변수를 다음 절로 넘겨 조합할 수 있어요. 각 절은 현재 그래프 상태와 중간 결과 테이블을 받아 처리하고, 갱신된 상태와 결과를 다음 절에 넘겨줘요. 변수는 다른 연산에서 참조되면 다음 절로 암묵적으로 넘어가고, WITH 절로 명시적으로 넘길 수도 있어요. 어느 쪽으로도 넘어가지 않으면 폐기돼요.

MATCH (martin:Person)-[:ACTED_IN]->(movie:Movie)
WHERE martin.name = 'Martin Sheen' AND NOT EXISTS {
  MATCH (movie)<-[:DIRECTED]-(director:Person {name: 'Oliver Stone'})
}
RETURN movie.title AS movieTitle

파라미터 사용

MATCH 절은 파라미터와 함께 쓸 수 있어요. 값은 쿼리 텍스트에 박아 넣지 않고 파라미터로 넘길 수 있죠.

{ "movieTitle": "Wall Street", "actorRole": "Fox" }
MATCH (:Movie {title: $movieTitle})<-[r:ACTED_IN]-(p:Person)
WHERE r.role CONTAINS $actorRole
RETURN p.name AS actor, r.role AS role

경로 찾기

MATCH 절은 패턴에 맞는 전체 경로를 변수에 바인딩할 수도 있어요.

패턴에 맞는 모든 경로를 찾는 쿼리예요.

MATCH path = ()-[:ACTED_IN]->(movie:Movie)
RETURN path

WHERE 술어를 포함한 패턴의 경로도 찾을 수 있어요.

MATCH path = (:Person)-[:ACTED_IN]->(movie:Movie)<-[:DIRECTED]-(:Person)
WHERE movie.title = 'Wall Street'
RETURN path

여러 MATCH 절과 WITH·절 조합

MATCH 절을 연속으로 이어 쓸 수도 있어요. 첫 MATCH의 결과 변수(movie)를 두 번째 MATCH에서 재사용하면, Martin Sheen이 출연한 영화들을 감독한 감독들을 찾을 수 있어요.

MATCH (:Person {name: 'Martin Sheen'})-[:ACTED_IN]->(movie:Movie)
MATCH (director:Person)-[:DIRECTED]->(movie)
RETURN director.name AS director, movie.title AS movieTitle

라벨이나 타입은 파라미터·변수·표현식으로 동적으로 참조할 수도 있어요. 다만 동적 값을 쓰는 MATCH 쿼리는 정적 값보다 성능이 떨어질 수 있어요. 예를 들어 버전에 따라 프로퍼티 인덱스를 활용하지 못하고 전체 노드 스캔을 할 수도 있으니, 실제 운용에서는 주의해서 써야 해요.

더 알아보기