기타/프로그래밍

[그래프 데이터베이스][무작정해보기] [14/30] count, collect, size,map, list 활용하기

코드아키택트 2021. 2. 17. 21:11
반응형

데이터 집계하기

기본적으로 Neo4j에서는 데이터를 모아줌

아래의 Cypher문을 작동했을 때 결과

MATCH (p:Person)-[:REVIEWED]->(m:Movie)
RETURN  p.name, m.title

 위의 결과를 잘 보면 오른쪽에 "The Replacements"가 연속되고 그 후 왼쪽에 "Jessica Thompson"이 연속되는 것을 볼 수 있음.

 

 

 

결과를 List로 모으기

Neo4j에서는 자료를 List형태로 모을 수 있음

다음 예시는 톰크루즈가 연기한 영화들을 리스트로 보여줌

MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WHERE p.name ='Tom Cruise'
RETURN collect(m.title) AS `movies for Tom Cruise`

위와 같이 리스트로 묶여서 나오는 것을 볼 수 있음

 

비교를 위해 collect 없이 해봄

MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WHERE p.name = 'Tom Cruise'
RETURN m.title AS `movies for Tom Cruise`

줄마다 하나씩 나오는 것을 볼 수 있음

 

 

 

노드 모으기

위와 같은 원리로 노드도 리스트로 모을 수 있음. 단, 그래프로 봤을때 차이는 없음

MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WHERE p.name ='Tom Cruise'
RETURN collect(m) AS `movies for Tom Cruise`

테이블로 보면 아래와 같음

 

마찬가지로 비교를 위해 Collect가 없는 사이퍼문 결과 생성

MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WHERE p.name ='Tom Cruise'
RETURN m AS `movies for Tom Cruise`

위와 다르게 각 노드값앞에 숫자가 붙은 것을 볼 수 있음. 지금은 GUI로 보기때문에 큰 차이는 아니지만, 나중에 API등을 통해 연결할때 큰 차이를 가져올 것 같음

 

 

 

Count

특정 query 결과가 몇번 나타나는지 셀 수 있음. 아래는 특정 배우가 특정 감독과 몇번의 collaboration과 어떤 작품들을 했는지 보여줌

MATCH (actor:Person)-[:ACTED_IN]->(m:Movie)<-[:DIRECTED]-(director:Person)
RETURN actor.name, director.name,
       count(m) AS collaborations, collect(m.title) AS movies

director.name을 기준으로 그룹이 만들어 진 것을 볼 수 있음

 

 

 

size

카운트 대신에 쓸 수 있음

MATCH (actor:Person)-[:ACTED_IN]->(m:Movie)<-[:DIRECTED]-(director:Person)
RETURN actor.name, director.name, size(collect(m)) AS collaborations,
       collect(m.title) AS movies

결과는 위와 동일하기 때문에 생략함

 

 

 

리스트

각 영화에 캐스팅된 사람들 쿼리하기.

MATCH (a:Person)-[:ACTED_IN]->(m:Movie)
RETURN m.title, collect(a) as cast, size(collect(a)) as castSize

왼쪽 부터 영화 제목, 각 노드들(리스트 구조), 리스트 크기 순서로 나오는 것을 볼 수 있음. 또한 노드들은 {},{},{} 구조로 나오는 것을 볼 수 있음.

 

 

리스트에서 문자열(String)사용하기

노드의 전체 값을 쿼리하기보단 필요한 값만 쿼리할 때가 많음. 아래 예제는 배우 이름만 리스트로 뽑아내는 과정

MATCH (a:Person)-[:ACTED_IN]->(m:Movie)
RETURN m.title, collect(a.name) as cast, size(collect(a.name)) as castSize

특정 영화에서 연기한 배우들의 이름과 그 크기를 보여줌. 결과를 보기전에 예상해보는게 연습에 좋은 것 같음. 하나의 영화엔 여러명의 배우가 등장하니 영화를 중심으로 배우이름들과, 캐스팅 사이즈가 묶일 것임

 

 

리스트의 Element접근하기

다른 랭귀지의 리스트처럼 Index로 접근 가능

MATCH (a:Person)-[:ACTED_IN]->(m:Movie)
RETURN m.title, collect(a.name)[0] as `A cast member`,
       size(collect(a.name)) as castSize

영화에 출연한 배우들 중 0번 index에 있는 값만 뽑아냄. 

 위의 Query값과 비교해봤을때, 0번째 값이 나오는 것을 볼 수 있음. 또한 따로 Sorting은 되지 않음.

 

 

 

Map 다루기

파이썬의 Dictionary처럼 key/value 한쌍임. 한달에 포함된 날짜를 예로 들면

{Jan: 31, Feb: 28, Mar: 31, Apr: 30 , May: 31, Jun: 30 , Jul: 31, Aug: 31, Sep: 30, Oct: 31, Nov: 30, Dec: 31}

위와같이 표현 가능함

 

2월의 날짜만 뽑아내고 싶다면

RETURN {Jan: 31, Feb: 28, Mar: 31, Apr: 30 , May: 31, Jun: 30 ,
       Jul: 31, Aug: 31, Sep: 30, Oct: 31, Nov: 30, Dec: 31}['Feb'] AS DaysInFeb

 파이썬의 Dictionary와 비슷한 구조로 보임

 

하나의 노드도 map임. 노드마다 약간 차이는 있지만 {key:value,key:value(list),key:value(map)}의 구조를 가진것을 볼 수 있음.

 

 

Map projection

Map projection은 노드 안의 정보를 return하거나 생상하기 위해 노드를 받아올떄 사용함. 예를 들면 Movie 노드에는 title, released, tagline이 있지만 tagline을 제외한 title과 released만 받아오고 싶다면?

MATCH (m:Movie)
WHERE m.title CONTAINS 'Matrix'
RETURN m { .title, .released } AS movie

title과 released만 포함된 map이 생성됨

반응형