티스토리 뷰

Neo4j

Cypher - MERGE

joyHong 2020. 6. 15. 23:25

MERGE의 사용법은 대상이 존재하면 찾는 기능을, 존재하지 않으면 생성하는 기능을 한다고 생각하고 예제들을 살펴보도록 한다.

 

우선 그래프 안에 특정 노드가 있는 경우네는 MATCH 기능과 같이 작동한다.

1. 기 존재하는 패턴에 대한 merge

MERGE(n{name:"Hue"})
RETURN n

* 이전 포스팅들에서 예시로 적은 모든 쿼리들을 따라 수행했으면 이 포스팅에서와 똑같은 결과가 나올 것이다.

이 쿼리는 name이 Hue인 노드가 기존에 존재하기 때문에 그 노드가 결과로 리턴되었다.

주의할 점은 CREATE문의 경우 똑같은 이름인 Hue 가 존재하더라도 name이 유일한 값이라는 제약사항이 있지 않은 한 새로운 노드가 생성된다.(새로운 노드는 노드의 id가 다른다)

 

그렇다면 그래프에 존재하지 않는 노드를 MERGE로 실행하는 예시를 보도록 하자.

 

2. 존재하지 않는 새로운 패턴에 대한 merge

MERGE(n{name:"Jack"})
RETURN n

name이 Jack인 노드가 존재하지 않기에 새롭게 노드를 생성하여 결과로 리턴하였다.

 

그러면 이름은 같으나 노드의 레이블이 다른 경우의 예시를 보자.

 

3. 이름은 같으나 노드의 label이 다른 경우에 대한 merge

MERGE(n:Person{name:"Hue"})
RETURN n

label이 다르기 때문에 새로운 노드가 생성되었다.

 

3번 쿼리에 대하여 사실인지 확인하기 위해 다음과 같이 쿼리를 수행한다.

MATCH(n)
WHERE n.name="Hue"
RETURN n, labels(n)

두 노드 모두 name이 Hue이지만  label이 하나는 있고, 다른 하나는 없다. 서로 다른 노드인 것이다.

 

 

이번에는 MATCH문과 MERGE문을 함께 사용하면 새로운 기능처럼 사용이 가능하다.

 

4. 기존 노드의 property로부터 파생된 노드 merge

MATCH (n:Person)
WHERE EXISTS(n.eyes)
MERGE (c:Color { name: n.eyes })
RETURN n.name, n.eyes, c

이 예시는 eyes를 가진 노드를 MATCH문으로 찾은 후 그 값을 Color이라는 레이블을 가진 노드의 name으로 merge를 한다는 의미이다.

eyes를 가진 노드를 찾기 위해서 EXISTS( )를 사용하였고, 그 노드를 찾은 후 MERGE ( )를 통해 c 노드를 생성하였다.

(c:Color {name: n.eyes} ) 노드는 기존의 그래프에 존재하지 않기 때문에 새롭게 생성이 되는 것이다.

 

그럼 이 결과를 확인하기 위해 다음과 같이 쿼리를 수행하여 Color노드를 확인해 보자.

MATCH(c:Color)
RETURN c

이러한 구문은 노드 뿐만 아니라 관계에 대해서도 사용이 가능하다.

 

5. 기존의 관계 없으면 관계를 생성

MATCH (n:Person { name: 'Eskil' }),(m:Person { name: 'Hue' })
MERGE (n)-[r:KNOWS]->(m)
RETURN n.name, type(r), m.name

 

6. 여러 개의 관계에 대한 merge

MATCH (a:Person { name: 'Alice' }),(b:Person { name: 'Hue' }), (c{name:'Jack'})
SET c:Person
MERGE (a)-[r:KNOWS]->(b)-[:KNOWS]->(c)
RETURN a.name, b.name, c.name

 

MERGE 문에는  ON CREATE와 ON MATCH 를 함께 사용할 수 있다.

이 포스팅 맨 처음에 "대상이 존재하면 찾는 기능을, 존재하지 않으면 생성하는 기능을" 한다고 생각하고 시작했는데 ON CREATE와 ON MATCH는 이를 좀 더 명확하게 구분한다고 간단히 생각하면 편하다.

 

ON CREATE는 노드를 생성해야할 때 사용하고, ON MATCH는 노드를 찾을 때 사용한다고 다시 생각하고 예제를 살펴본다.

 

7. 노드가 생성되어져야 할 경우(, 동일한 노드가 존재하지 않는 경우) merge

MERGE (n:Person { name: 'Joy' })
ON CREATE SET n.name = 'Joy', n.eyes='Black', n:Person
RETURN n.name, n.eyes

MERGE를 통해 name이 Joy인 노드를 찾아 동일한 노드가 존재하지 않는 경우에 name, eyes 프로퍼티와 Person 레이블을 생성한다는 의미이다. 이 쿼리를 다시 실행시키면??

그때는 동일한 노드가 존재하기 때문에 ON CREATE 라인은 무시가 되고 기존의 노드가 반환된다.

 

8. 동일한 노드가 존재하는 경우 merge

MERGE (n:Person { name: 'Hue' })
ON MATCH SET  n.eyes='red', n.age=22
RETURN n.name, n.age, n.eyes

ON MATCH는 동일한 노드가 존재하는 경우 SET을 통해 프로퍼티를 추가하는 동작을 실행한다.

 

 

그럼 이 두개의 구문을 함께 사용하면 어떻게 될까?

그러한 경우에는 if ~ then ~과 같은 기능을 하게 된다.

존재하면 ON MATCH 쿼리를 존재하지 않으면 ON CREATE 쿼리를 수행하게 된다.

 

9. 노드의 존재 여부에 따라 동작하는 merge - 1

MERGE (n:Person { name: 'Jack' })
ON CREATE SET n.eyes='blue', n.age=30
ON MATCH SET  n.eyes='red', n.age=27
RETURN n.name, n.age, n.eyes

이 쿼리는 Jack이 존재하기 때문에 ON MATCH를 수행하였다.

 

10. 노드의 존재 여부에 따라 동작하는 merge - 2

MERGE (n:Person { name: 'Joy', age:'22' })
ON CREATE SET n.age=22
ON MATCH SET  n.age=27
RETURN n.name, n.age

이 쿼리는 기존에 나이가 22인 Joy가 존재하지 않기 때문에 ON CREATE가 수행되었다.

 

그럼 마지막으로 MERGE를 여러개 사용할 수 있을까?

대답은 아래의 쿼리와 같다.

 

11. 노드와 관계를 생성

MATCH (n:Person)
WHERE EXISTS(n.eyes)
MERGE (c:Color { name: n.eyes })
MERGE (n)-[r:EYES_COLOR]->(c)
RETURN n.name, r, c

여러개의 MERGE를 사용해 노드와 관계 생성

 

지금까지 포스팅한 내용의 쿼리를 모두 실행하게 되면 아래의 그림과 같은 그래프가 생성되어진다.

중간 결과 확인

MATCH (a:Person)--(m)
RETURN a, m

 

다음으로는 MATCH 에 대한 좀 더 상세한 사용법을 살펴보도록 하겠다.

 


참조 : 

https://neo4j.com/docs/cypher-manual/4.0/

'Neo4j' 카테고리의 다른 글

Cypher - INDEX & CONSTRAINT  (0) 2020.06.16
Cypher - MATCH (2)  (0) 2020.06.15
Cypher - REMOVE & DELETE  (0) 2020.06.15
Cypher - SET & CREATE  (0) 2020.06.15
Cypher - MATCH (1)  (0) 2020.06.15
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함