Neo4J에서는 SQL이 아닌 Cypher라는 선언형 프로그래밍 언어를 통해 DBMS에 질의를 하게 된다. 이번 글은 DBMS 질의어의 기본인 생성, 검색, 수정, 삭제에 대한 Cypher문을 공부해보고자 한다.
CREATE
CREATE는 노드및 관계 를 생성하는데 사용되는 문법이다.
다음은 노드를 생성하는데 사용되는 명령문의 예시이다.
CREATE (ee:Person {name: 'Emil', from: 'Sweden', kloutScore: 99})
> ()안에는 이러한 노드에 대한 정보가 들어가게 된다.
> ee:Person에서 ee는 노드 variable에 해당하고 Person은 노드 Label에 해당한다.
Node Label
Label이 같은 노드들은 같은 set에 묶이게 되고 이러한 set을 통해 Domain이 형성된다.
노드는 zero or many lable을 가질 수 있다.
Node variable
Variable은 특정 라벨에 해당하는 노드를 만들 때 그 노드에 대한 변수의 역할을 한다
> {}안에 key-value 쌍으로 들어가는 것은 property들이다.
이를 종합해서 설명하자면 우리가 만든 ee라는 노드는 Person이라는 라벨을 가지며 name, from, kloutScore라는 특성을 가지며 각각 "Emil", "Sweden", 99라는 value를 가진다.
다음은 관계를 생성하는데 사용되는 명령문의 예시이다.
MATCH
(a:Person),
(b:Person)
WHERE a.name = 'A' AND b.name = 'B'
CREATE (a)-[r:RELTYPE {name: a.name + '<->' + b.name}]->(b)
> 우리가 관계를 생성하고자 하는 노드들의 variable을 MATCH를 통해 가져오게 되고 이를 바탕으로 관계를 형성한다.
> 이후 관계를 만드는데 a,b는 노드에 대한 variable로 관계의 방향성을 화살표로 표현하게 된다.
> 관계라는 객체를 형성할때는 노드를 형성할때와 마찬가지로 r이라는 variable과 RELTYPE이라는 label로 이를 선언하게 된다.
> 관계 또한 property를 가질 수 있다. 이는 RELTYPE 다음에 나오는 {}를 보면 알 수 있다.
MATCH
노드 검색
Match는 Node나 Relation에 대한 패턴을 생성하여 이를 바탕으로 데이터를 DB상에서 검색을 하는 명령어이다.
다음은 노드를 검색하는 MATCH문이다.
MATCH (ee:Person) WHERE ee.name = 'Emil' RETURN ee;
이는 SQL 문의 SELECT 문과 매우 비슷하다. 해당 쿼리의 결과는 다음과 같은 Json형태로 반환된다.
[
{
"keys": [
"ee"
],
"length": 1,
"_fields": [
{
"identity": {
"low": 0,
"high": 0
},
"labels": [
"Person"
],
"properties": {
"name": "Emil",
"from": "Sweden",
"kloutScore": {
"low": 99,
"high": 0
}
},
"elementId": "0"
}
],
"_fieldLookup": {
"ee": 0
}
}
]
반환된 Json의 형태는 key로 우리가 받고자했던 변수명이 들어가 있고 이에 대한 _fields영역에 관련 정보가 들어가서 반환된다.
이를 통해 우리는 이름이 Emil이라는 노드의 정보를 반환 받았다.
하지만 이러면 그래프 DB를 사용하는 의미가 없지 않는가.
관계를 이용한 검색
다음은 노드를 검색하는데 있어 관계를 이용하여 검색하는 명령문이다.
MATCH (ee:Person)-[:KNOWS]-(friends)
WHERE ee.name = 'Emil' RETURN ee, friends
해당 명령문을 말로 표현을 하자면 다음과 같다.
Person이라는 Lable을 가진 노드들 중 name이 Emil이라는 노드를 반환하고 이들과 KNOWS라는 관계로 연결된 노드들을 반환해라.
해당 명령문의 결과로 받는 Json은 ee와 friends 쌍으로 받게 되고 결과는 다음과 같다.
[
{
"keys": [
"ee",
"friends"
],
"length": 2,
"_fields": [
{
"identity": {
"low": 0,
"high": 0
},
"labels": [
"Person"
],
"properties": {
"name": "Emil",
"from": "Sweden",
"kloutScore": {
"low": 99,
"high": 0
}
},
"elementId": "0"
},
{
"identity": {
"low": 2,
"high": 0
},
"labels": [
"Person"
],
"properties": {
"name": "Ian",
"from": "England",
"title": "author"
},
"elementId": "2"
}
],
"_fieldLookup": {
"ee": 0,
"friends": 1
}
},
{
"keys": [
"ee",
"friends"
],
"length": 2,
"_fields": [
{
"identity": {
"low": 0,
"high": 0
},
"labels": [
"Person"
],
"properties": {
"name": "Emil",
"from": "Sweden",
"kloutScore": {
"low": 99,
"high": 0
}
},
"elementId": "0"
},
{
"identity": {
"low": 1,
"high": 0
},
"labels": [
"Person"
],
"properties": {
"learn": "surfing",
"name": "Johan",
"from": "Sweden"
},
"elementId": "1"
}
],
"_fieldLookup": {
"ee": 0,
"friends": 1
}
}
]
반환되는 Json 변경하기
collect
하지만 위와 같은 쿼리문을 반환 받게 되면 우리가 원하지 않는 값들 또한 포함이 되어 있다. 이러한 경우는 collect()를 사용해서 우리가 원하는 결과만 받을 수 있게 된다.
MATCH (ee:Person)-[:KNOWS]-(friends)
WHERE ee.name = 'Emil' RETURN collect(ee.name), collect(friends.name)
다음과 같이 query문을 작성하게 되면 Node에 name에 해당하는 property의 value만 반환 받을 수 있게 된다.
[
{
"keys": [
"collect(ee.name)",
"collect(friends.name)"
],
"length": 2,
"_fields": [
[
"Emil",
"Emil"
],
[
"Ian",
"Johan"
]
],
"_fieldLookup": {
"collect(ee.name)": 0,
"collect(friends.name)": 1
}
}
]
AS
반환 되는 JSON의 keys를 우리가 검색한 조건이 아닌 custom하게 받고 싶다면 AS를 다음과 같이 사용하면 된다.
MATCH (ee:Person)-[:KNOWS]-(friends)
WHERE ee.name = 'Emil' RETURN collect(ee.name) AS myName, collect(friends.name) AS friendsName
[
{
"keys": [
"myName",
"friendsName"
],
"length": 2,
"_fields": [
[
"Emil",
"Emil"
],
[
"Ian",
"Johan"
]
],
"_fieldLookup": {
"myName": 0,
"friendsName": 1
}
}
]
SET
노드의 Property를 변경할 때 사용하는 명령어이다.
MATCH (n {name: 'Andy'})
SET n.surname = 'Taylor'
RETURN n.name, n.surname
SET을 쓰기 위해서는 MATCH로 우리가 바꾸고자 하는 노드를 특정 시키고 해당 노드의 property에 대한 수정을 가하면 된다.
DELETE
SET과 매우 비슷한 방식으로 사용한다. MATCH를 통해 우리가 Node나 Property를 찾게 되면 이에 대한 삭제를 진행하게 된다.
Node 삭제
MATCH (n:Person {name: 'Tom Hanks'})
DELETE n
Relation 삭제
MATCH (n:Person {name: 'Laurence Fishburne'})-[r:ACTED_IN]->()
DELETE r
출처
https://neo4j.com/docs/cypher-manual/current/clauses/create/
https://neo4j.com/docs/cypher-manual/current/clauses/match/
https://neo4j.com/docs/cypher-manual/current/clauses/set/
https://neo4j.com/docs/cypher-manual/current/clauses/delete/
'개발 > Neo4j' 카테고리의 다른 글
[Neo4j] Neo4j의 메모리 구성 (0) | 2023.05.06 |
---|---|
[Neo4j] Neo4j Docker Compose (0) | 2023.05.03 |
[Neo4j] 그래프 데이터베이스란? (0) | 2023.05.03 |