Neo4j Cypher 소개
Cypher란 무엇인가?
Cypher(사이퍼)란? Neo4j사에서 개발 데이터베이스 쿼리에 사용되는 그래프 쿼리 언어이다. Cypher 쿼리는 SQL과 같은 형식이므로 강력하고 다양한 데이터 표현을 할 수 있다.
Cypher는 Neo4j의 기본 인터페이스로 패턴과 관계를 시각적으로 일치시키는 방법을 제공한다.
Cypher는 (nodes)-[:ARE_CONNECTED_TO]->(otherNodes)
와 같은 패턴이 사용된다. 소괄호()
는 노드를 대괄호[]
는 관계를 의미하며, -
와 ->
는 노드와 노드 사의 관계 반향을 나타낸다.
Cypher를 사용하여 표현적이고 효율적인 쿼리를 구성하여 그래프에서 모든 종류의 생성, 읽기, 업데이트, 삭제(CRUD)를 수행할 수 있다.
Cypher Syntax
Cypher는 사람이 읽을 수 있도록 설계되었기 때문에, 구문을 시각적이고 쉽게 이해할 수 있도록 영어와 형상(또는 인물)을 기반으로 구성된다.
- Jennifer는 기술로 그래프를 좋아한다.
- Jennifer는 2018년 이후로 Michael과 친구이다.
- 제니퍼는 Neo4j 회사에 일한다.
사이퍼 주석
//
로 시작되며 뒤에 원하는 문구를 입력
Cypher의 주석은 많은 프로그래밍 언어와 동일하다. //
로 시작하여 이어서 텍스트를 작성하여 주석을 주가한다. 다른 언어와 마찬가지로 두 개의 슬래시로 줄을 시작하면 해당 줄의 모든 내용이 주석이 된다.
Cypher에서 노드 표현
Cypher는 패턴에 ASCII-Art1를 사용하므로, 위 패턴의 각 구성 요소를 시각적으로 표현할 수 있는 방법이 필요하다. 속성 그래프 모델의 주요 구성 요소는 노드와 관계이며, 노드는 그래프의 데이터 엔터티이며 데이터 모델에서 명사 또는 개체를 찾아 노드를 식별할 수 있다. 이 예제에서 Jennifer, Michael, Graphs는 Neo4j 노드이다.
Cypher에서 노드를 나타내기 위해 (node)
이렇게 노드를 소괄호로 묶는다. 시각적 표현이 데이터 모델의 노드에 사용하는 원과 소괄호가 유사하게 느껴진다.
노드 변수
나중에 노드를 참조하기 위해 (p)
:person 또는 (t)
:thing과 같이 변수를 지정할 수 있다. 실제 쿼리에서는 (person)
또는 (thing)
와 같이 더 길고 표현력이 풍부한 변수 이름을 사용할 수 있다. 프로그래밍 언어 변수와 마찬가지로 원하는 대로 변수 이름을 지정하고, 이후레 쿼리에서 동일한 이름으로 변수를 참조할 수 있다.
이뿐 아니라, 빈 소괄호를 입력하여 익명의 노드를 지정할 수도 있다.
노드가 반환 결과와 관련이 없는 경우, 빈 소괄호(()
)를 사용하여 익명 노드를 지정할 수 있다. 이는 나중에 쿼리에서 이 노드를 반환할 수 없음을 의미한다.
노드 레이블(Node Labels)
속성 그래프 데이터 모델에 노드 레이블을 지정하여, 유사한 노드를 함께 그룹화할 수도 있다. 레이블은 일종의 태그와 같으며, 이를 통해 찾거나 생성할 특정 유형의 엔터티를 지정할 수 있다. 이 예제에서는 Person
, Technology
는 Company
레이블이다.
레이블은 SQL에 특정 행을 검색할 테이블을 지정하는 것과 같이 생각할 수 있다. Person
, Employee
, Customer
테이블에서 사람의 정보를 쿼리하도록 SQL에 지시하는 것과 마찬가지로 Cypher에게 해당 정보에 대한 레이블만 확인하도록 지시할 수도 있다. 이를 통해 Cypher는 엔터티를 구별하고 쿼리 실행을 최적화할 수 있다. 가능한 경우 쿼리에 노드 레이블을 사용하는 것을 권장한다.
Cypher에 레이블을 지정하지 않으면, 일치하지 않는 노드 범주를 필터링하기 위해, 쿼리가 데이터베이스의 모든 노드를 확인하게 된다. 그러므로, 매우 큰 그래프를 조회하는 쿼리는 오래 걸리게 된다.
예: Cypher의 노드
위의 그래프 예제를 사용하여 노드를 지정하는 방법을 살펴보겠다.
() // 익명 노드(레이블 또는 변수 없음)는 데이터베이스의 모든 노드를 참조할 수 있다.
(p:Person) // 변수는 p이고, 레이블 Person이다.
(:Technology) // 변수는 없고, 레이블은 Technology 이다.
(work:Company) // 변수는 work이고, 레이블은 Company 이다.
Cypher의 관계 표현
그래프 데이터베이스의 기능을 최대한 활용하려면 노드 간의 관계도 표현해야 한다. 관계는 화살표 -->
또는 <--
두 노드 사이를 사용하여 Cypher에서 표시된다. 구문이 시각적 표현에서 노드를 연결하는 화살표와 선(line)처럼 어떻게 보이는지 확인한다. 노드 연결 방법(관계 유형) 및 관계와 관련된 모든 속성과 같은 추가 정보는 화살표 내부의 대괄호([]
) 안에 배치할 수 있다.
이 예제에서 노드 사이에 LIKES
,WORKS_FOR
, IS_FRIENDS_WITH
선은 노드간의 관계이다.
방향이 지정되지 않은 관계는 화살표 없이 두 개의 대시(--
)만으로 표시된다. 이는 관계가 어느 방향으로든 향할 수 있다는 것을 의미한다. 데이터베이스에 방향을 등록해야 하지만, 물리적 방향에 관계없이 Cypher가 특정 방향을 무시하고, 관계 및 연결된 노드를 검색하는 무방향 관계와 일치시킬 수 있다. 이를 통해 쿼리가 유연해지고 사용자가 데이터베이스에 저장된 관계의 물리적 방향을 몰라도 된다.
데이터가 하나의 관계 방향으로 저장되고, 쿼리가 잘못된 방향을 지정하게 되면 Cypher는 결과를 반환하지 않는다. 방향이 확실하지 않을 수 있는 이러한 경우 무방향 관계를 사용하고 일부 결과를 검색하는 것이 좋다.
// 데이터가 아래와 같은 방향으로 저장되어 있다. CREATE (p:Person)-[:LIKES]->(t:Technology) // 쿼리에 관계는 반대로 조회하면, 결과를 반환하지 않는다. MATCH (p:Person)<-[:LIKES]-(t:Technology) // 방향이 확실하지 않으면, 무방향 관계로 쿼리하는 것이 좋다. MATCH (p:Person)-[:LIKES]-(t:Technology)
관계 유형
관계 유형은 레이블이 노드를 그룹화하는 방식과 유사하게 관계를 분류하고 관계에 의미를 추가한다. 그래프 데이터 모델에서 관계는 노드가 연결되고, 서로 관련되는 방식을 보여준다. 일반적으로 동작이나 동사를 찾아 데이터 모델에서 관계를 식별할 수 있다.
노드 간에 원하는 모든 유형의 관계를 지정할 수 있는데, 동사와 행위 등으로 좋은 명명 규칙을 사용하는 것이 좋다. 잘못된 관계 유형 이름은 Cypher를 읽고 쓰는 것을 더 어렵게 만든다(잘 작성하게 되면, 영어처럼 보일 것이다!).
예를 들어, 예제 그래프에서 관계 유형을 살펴보겠다.
[:LIKES]
- 노드를 관계의 양쪽에 배치할 때 의미가 있다(Jennifer LIKES Graphs).[:IS_FRIENDS_WITH]
- 노드를 배치할 때 의미가 있다(Jennifer IS_FRIENDS_WITH Michael).[:WORKS_FOR]
- 노드에 적합하다(Jennifer WORKS_FOR Neo4j).
관계 변수
노드에서 했던 것처럼 나중에 쿼리에서 관계를 참조하려면, [r]
또는 [rel]
와 같은 변수를 지정할 수 있다. [likes]
또는 [knows]
와 같이 더 길고 표현력이 풍부한 변수 이름을 사용할 수도 있다. 나중에 관계를 참조할 필요가 없으면 두 개의 대시 --
, -->
,<--
를 사용하여 익명 관계를 지정할 수 있다.
예를 들어, 관계 및 해당 세부 정보를 참조하기 위해 나중에 쿼리에서 rel
변수를 사용하여 -[rel]->
또는 -[rel:LIKES]->
으로 호출 할 수 있다.
-[LIKES]->
와 같은 관계 유형 앞에 콜론(:
)이 빠지게 되면, 변수를 나타낸다. 이는 관계 유형이 아니게 된 것이고, 관계 유형이 선언되지 않았기 때문에 Cypher는 모든 유형의 관계를 검색하게 된다.
노드 또는 관계 속성
여기서는 노드, 관계 및 레이블에 대해 Cypher를 작성하는 방법에 대해 설명하였다. 속성 그래프 데이터 모델의 마지막 부분은 속성에 대한 것이다. 속성은 노드 및 관계에 추가 세부 정보를 제공하는 이름-값 쌍이라는 점을 기억하자.
Cypher에서 이를 나타내기 위해 노드의 괄호 또는 관계의 괄호 안에 중괄호를 사용할 수 있다. 속성의 이름과 값은 중괄호 안에 들어간다. 예제 그래프에는 노드 속성(name
)과 관계 속성(since
)이 모두 존재한다.
-
노드 속성:
(p:Person {name: 'Jennifer'})
-
관계 속성:
-[rel:IS_FRIENDS_WITH {since: 2018}]->
속성은 다양한 데이터 유형의 값을 가질 수 있다. Cypher가 제공하는 전체 목록을 보려면 값 및 유형 에 대한 매뉴얼 섹션을 참조한다.
사이퍼의 패턴
노드와 관계는 그래프 패턴의 구조를 구성한다. 이러한 구조를 함께 사용하여, 단순하거나 복잡한 패턴을 표현할 수 있다. 패턴은 그래프의 가장 강력한 기능이다. Cypher에서는 연속 경로로 작성하거나 더 작은 패턴으로 분리하고 쉼표로 묶을 수 있다.
Cypher에서 패턴을 나타내기 위해서는 지금까지 배운 노드 구문과 관계 구문을 결합해야 한다.
예를 들어, Jennifer likes Graphs
을 Cypher에서 표현하면, 아래 코드와 같다.
(p:Person {name: "Jennifer"})-[rel:LIKES]->(g:Technology {type: "Graphs"})
Cypher의 이 부분은 우리가 원하는 패턴을 알려주지만, 기존 패턴을 찾을 것인지, 새 패턴으로 삽입할 것인지는 알려주지 않는다. Cypher에게 패턴으로 무엇을 하려는지 알려주려면 몇 가지 키워드를 추가해야 한다.
원문
-
오로지 텍스트와 특수문자만을 조합하여 사진이나 그림을 흉내내는 것을 말한다. ↩︎