기타/프로그래밍

[그래프 데이터베이스][무작정해보기] [10/30] Relation과 Property로 Query하기

코드아키택트 2021. 1. 22. 22:40
반응형

연습2 : 속성값으로 쿼리값 필터링 하기.

영화 데이터를 계속 사용함.

 

 

 

관계(Relationships)

관계는 복잡하고 깊은 데이터를 연결하는데 있어 Neo4j 그래프를 강력한 도구로 만들어준다.

  • 관계는 방향성(Directed)이 있는 연결로 두 노드 사이를 관계종류(Relationship type)로 연결한다.
  • 노드와 같이 속성(properties)을 가진다.
  • 노드를 찾을떄, 관계의 속성값을 이용할 수 있다.

빨간색이 관계.

ASCII art

노드와 관계 사이에서 데이터를 얻어내기 위한 syntax

()          // 노드
()--()      // 어떤 관계를 가진 두 노드
()-[]-()    // 어떤 관계를 가진 두 노드
()-->()     // 첫번째 노드가 두번째 노드에게 관계를 가지고 있다.
()<--()     // 두번째 노드가 첫번째 노드에게 관계를 가지고 있다.

 

 

 

관계를 이용한 Querying

MATCH 부분에 관계를 명시한다. 방향성을 명시하거나 그렇지 않을 수 있다.

 

노드 1에서 2로 특정 관계로 이어지는 경우

MATCH (node1)-[:REL_TYPE]->(node2)
RETURN node1, node2

 

노드 1에서 2로 이어지며, 두 관계중 하나라도 성사되는 경우. 즉, 방향성은 있돼 두가지 관계 중 하나라도 성사되면 return함.

MATCH (node1)-[:REL_TYPEA | REL_TYPEB]->(node2)
RETURN node1, node2

 

nod1 노드
REL_TYPE node1 에서 2로 이어지는 Relationship 종류
REL_TYPEA , REL_TYPEB node1 에서 2로 이어지는 Relationship 종류. 둘중 하나라도 존재하면 노드는 RETURN 됨
  노드

 

 

 

데이터 베이스 안의 관계 라벨 확인하기: CALL db.schema.visulization

 

 

쿼리에서 관계 이용하기

메트릭스(The matix)를 연기한 사람을 찾기

 

 

기본구조

MATCH (a:label)-[r:relationship]-(c:label{propertyKey:propertyValue})
RETURN a,r,c

 기본구조는 위와 같음. 메트릭스에셔 연기한 배우를 찾기위해선 아래와 같이 쓰면 됨.

MATCH (a:Person)-[r:ACTED_IN]-(c:Movie{title:'The Matrix'})
RETURN a,r,c

 

 

 

 

라벨을 꼭 붙이자.

퍼포먼스 차이가 있다.

 

140개 노드와 179개의 관계으 경우의 속도 차이.

 

 

여러 관계에 대해 Query

 톰행크스가 감독했거나 연기한 영화(톰 행크스가 감독하거나 연기하거나 감독 및 연기 둘다한 영화)
MATCH (p:Person {name:'Tom Hanks'})-[r:ACTED_IN|DIRECTED]->(m:Movie)
RETURN p,r,m

 

 

 

익명 노드 사용하여 원하는 정보만 보기

 가령 메트릭스에서 연기한 배우들을 찾고자할때, 배우 정보만 필요하고 영화에 대한 정보가 필요없다면? 배우(Person)노드는 변수에 지정하고 나머지는 변수에 지정하지 않는다.

 

Person 노드에 관해선 p라는 변수를 지정했지만 나머지는 지정하지 않았다.

 

 

익명 관계를 이용해서 영화와 어떤 관련이라도 있는 사람들 찾아내기

 만약 메트릭스와 어떠한 관계(연기,감독,연출 등)라도 있는사람들을 찾아내고 싶다면? 관계부분을 비워둔다. 비우는 방식은 아래의 4가지로 구현할 수 있다.

 

방향성을 주는 경우(-->)
MATCH (p:Person)-->(m:Movie {title: 'The Matrix'})
RETURN p, m
MATCH (m:Movie{title: 'The Matrix'})<--(p:Person)
RETURN p, m
방향성을 안주는 경우(--,-[]-)
MATCH (p:Person)--(m:Movie {title: 'The Matrix'})
RETURN p, m
MATCH (p:Person)-[]-(m:Movie {title: 'The Matrix'})
RETURN p, m

 

4가지 경우 결과는 동일하게 나온다.

 

 

한걸음 더 나아가기: 키아누 리브스가 관여된 아무 영화나 찾아보기.

MATCH (m:Movie)<--(p:Person{name:'Keanu Reeves'})
RETURN m,p

 

키아누 리브스는 연기밖에 안했나보다.

 

 

관계타입 받아오기

 type()이라는 기능을 통해 타입을 알 수 있음. 여기서 타입이란 노드의 라벨과 같음.

 

각 배우들이 메트릭스와 어떤 관계를 가지고 있는지 볼 수 있음.

 

 

 

관계속성값

 노드가 Key를 통해 속성값을 가질 수 있었듯이, 관계도 속성값을 가질수 있음. 이를 통해 그래프 모델이 더 많은 정보를 전달할 수 있게함.

 

 

예시:  Jessica Thompson 과 James Thompson 이라는 사람이 다빈치 코드를 리뷰함. 각각 요약한 내용과, 리뷰 점수가 있음.

 

 

 

관계 속성으로 필터링 하기

 다빈치 코드에 65점 준 사람 필터링 하기
MATCH (p:Person)-[:REVIEWED{rating:65}]->(:Movie{title:'The Da Vinci Code'})
RETURN p.name

 

 

 

그래프 패턴

그래프가 쿼리문에 대해 어떻게 탐색되는 지는 관계의 방향성과 MATCH안에 명시된 패턴에 따라 좌우된다.

FOLLOWS 관계는 방향성을 지닌다.

 

 

패턴을 사용해서 쿼리하기 : Angela Scope를 팔로우하는 모든 사람 찾아내기

MATCH (p:Person)-[:FOLLOWS]->(:Person{name:'Angela Scope'})
RETURN p

 

팔로어가 한명밖에 없다니.
쿼리 엔진은 Angela Scope를 먼저 찾은 후, Angela Scope를 Follows하는 사람을 찾음.

 우선 Angela Scope를 찾은 후 이것이 Query anchor가 된다. 그런 후 Angela Scope를 향하는 모든 관계를 찾는다. 위의 경우 오직 한명밖에 없기때문에, Paul Blythe가 결과값으로 나온다.

 

 

탐색방향 뒤집기 : Angela Scope가 Following 하는 사람 찾기

 Query문에서 화살표만 바꾸면 된다.
MATCH (p:Person)<-[:FOLLOWS]-(:Person{name:'Angela Scope'})
RETURN p

 

 위의 경우에도 마찬가지로 Angela Scope가 Query Anchor가 되고 이것을 중심을 바깥을 향하는 관계를 찾는다.

 

 

양방향 관계 찾기: Angela Scope의 Following과 Follower찾기.

Angela Scope를 중심으로 Following 또는 Followed 하는 관계

MATCH  (p1:Person)-[:FOLLOWS]-(p2:Person {name:'Angela Scope'})
RETURN p1, p2

 

화살표(->,<- 대신 -만 사용됨)

 Angela Scope가 Query Anchor가 되고 이로부터 바깥 또는 안쪽을 향하는 Follows를 찾는다.

 

 

여러 관계 탐색하기: 2촌 이상 찾기

 Jessica Thompson의 팔로워의 팔로워(짝사랑 2촌?)

 

Jessica Thompson이 Query Anchor가 되고 2단계 밖의 노드를 찾는다.

 

MATCH  (p:Person)-[:FOLLOWS]->(:Person)-[:FOLLOWS]->(:Person {name:'Jessica Thompson'})
RETURN p
MATCH  (p:Person)-[:FOLLOWS]->()-[:FOLLOWS]->(:Person {name:'Jessica Thompson'})
RETURN p
MATCH  (p:Person)-[:FOLLOWS*2]->(:Person {name:'Jessica Thompson'})
RETURN p

 위의 세 코드 모두 동일한 결과를 내놓는다. 하지만 될 수 있으면 노드라벨을 쓰는것이 속도측면에서 빠를 것이라고 했으니, 되도록 첫번째 방법을 사용하도록 하자.

 

Jessica Thompson의 Follower의 Follower는 한명

 

Path 반환하기

 변수에 Path를 할당해서 쓸 수도 있다.
MATCH path = (:Person)-[:FOLLOWS]->(:Person)-[:FOLLOWS]->(:Person {name:'Jessica Thompson'})
RETURN path

Path를 변수에 넣지 않고 쓸 경우 아래와 같이 쓸 수 있다.

MATCH (p1:Person)-[:FOLLOWS]->(p2:Person)-[:FOLLOWS]->(p3:Person {name:'Jessica Thompson'})
RETURN p1, p2, p3

 

path로 할시, 모든 노드들과 관계를 보여준다.

 

 

여러 Path 반환하기

'Ron Howard'가 감독한 모든 영화와 그 영화들을 연기한 모든 배우에 대한 모든 Path

 

path를 return하도록 한다면 아래와 같이

MATCH path = (:Person {name:'Ron Howard'})-[:DIRECTED]->(:Movie)<-[:ACTED_IN]-(:Person)
RETURN path

 

한땀한땀 쓴다면 다음과 같이

MATCH (p1:Person {name:'Ron Howard'})-[:DIRECTED]->(m:Movie)<-[:ACTED_IN]-(p2:Person)
RETURN p1,m,p2

 

반환된 결과. 조금 개구리 발가락같이 생겼다.
두 방식의 퍼포먼스 차이는 없었다.

 

참고자료


neo4j.com/graphacademy/training-querying-40/01-querying40-introduction-to-cypher/#_exercise_2_filtering_queries_using_property_values

반응형