개발/기술

cypher

kwony 2022. 2. 14. 20:00

cypher는 Graph Database 인 Neo4j 에서 Query를 작성할 때 사용할 수 있는 언어다. 처음 보면 생소하지만 사용하다보면 SQL 과 흡사한 점이 많아 금방 배울 수 있다. 노드와 관계 그리고 속성을 정의하는 쿼리라는 점에 주목해서 보자. 

 

다음 문장을 나타내는 관계를 만든다고 해보자

 

Mike writes Neo4j
Son reads Neo4j
Mike likes Son

 

CREATE 

 

문장에서 각 주어와 목적어는 관계상에서 Node로 표현할 수 있으며 각각의 Node는 Label로 묶어 줄 수 있다. Mike와 Son은 User라는 라벨로 표현하고 Neo4j 은 Book 라벨로 표한하자. 각 Node를 Cypher를 이용하면 아래의 쿼리로 세개의 노드를 생성할 수 있다.

 

create(:User{name:"Mike"})
create(:User{name:"Son"})
create(:Book{name:"Neo4j"})

 

create(variable:LabelName{property})

 

create는 생성을 담당하는 cypher 예약어다. 소괄호 내부 규칙은 위의 문장을 따른다. 변수는 다른 쿼리에서 사용할 때 사용하기 때문에 현재는 따로 작성하지 않았고 라벨 이름과 라벨에 해당하는 속성값을 설정해 노드를 만들었다. 실행 결과 아래 그림과 같이 세개의 노드가 생성되는 것을 확인 할 수 있다.

 

 

MATCH

 

match(variable:LabelName) where variable.property=something and.. return variable

 

MATCH 예약어는 SQL의 SELECT와 비슷한 역할을 하는 것으로 노드 또는 관계를 찾을 때 사용한다. CREATE와 비슷한 문법을 가지며 조건문과 return 값이 있는것만 다르다. 방금 생성한 세개의 노드 중에서 User 라벨을 가진 노드만 뽑아 보자. 

 

match(a: User)
return a

 

Match(a:User) 구문에선 a 라는 변수를 할당했다. 해당 match 구문에 해당되는 노드의 집합은 a 변수에 표현된다. 그리고 a 옆에는 User라는 라벨을 표현했는데 이것은 User 라벨에 해당하는 노드만 보겠다는 의미다. 별도의 조건 문이 없다면 a는 User 라벨을 갖고 있는 모든 집합을 표현하게 된다. 마지막으로 return a 구문은 a의 집합을 리턴하겠다는 의미다. 실행 결과 아래 그림과 같이 두개의 노드가 표현된다.

 

 

where 문을 넣어서 조건을 추가할 수 있다. 아래 쿼리는 Mike 이름을 가진 노드를 리턴하게 된다.

 

match(a: User) where a.name="Mike" return a

 

CREATE/MATCH RELATION

 

Mike writes Neo4j Tutorial

 

이제 위 문장을 관계를 표현해보자. 관계를 추가할 때는 노드가 두 개가 필요하다. 그래서 노드를 추가할 때와는 다르게 MATCH를 이용해서 관계로 연결 할 두 노드를 찾은 후 변수에 할당해 관계를 형성할 때 이용한다. 아래 쿼리를 보면 m 변수에는 Mike라는 노드를 찾아왔고, b 변수에는 Neo4j 노드를 찾아왔다. create 가 관계를 생성하는 작업이다. 관계의 방향성은 C언어의 포인터를 작성하는 방법으로 표현하며 두 노드 사이에 대괄호로 표현한 부분이 관계를 설정하는 부분이다. 관계의 이름은 예시로 있는 문장을 표현하기 쉽게 WRITE로 정의했다.

 

match (m: User) where m.name="Mike"
match (b :Book) where b.name="Neo4j"
create (m)-[r:WRITE]->(b)

 

생성한 관계는 아래 구문으로 확인 할 수 있다. WRITE라는 관계를 가진 모든 노드를 찾겠다는 의미다. User 라벨을 붙인 모든 노드를 찾을 때처럼 여기서도 WRITE 관계로 연결된 모든 노드를 찾도록 표현 할 수 있다. 실용적으로 표현이 가능해서 편리하다.

 

match (a)-[r:WRITE]-() return a

 

 

 

쿼리를 응용해서 나머지 관계도 생성해보자

 

match (m: User) where m.name="Mike" match (s: User) where s.name="Son" create (m)-[:LIKE]->(s)
match (s: User) where s.name="Son" match (b: Book) where b.name="Neo4j" create (s)-[:READ]->(b)

 

MATCH를 응용해 데이터베이스 상에 있는 모든 노드를 리턴하게해 전체 관계를 볼 수 있다. 앞서 정의하기로한 관계가 모두 표현된 것을 확인 할 수 있다. 

 

MATCH(n) return n