본문 바로가기
Back-End

Neo4j 설치하고 사용해보기

by 이곳느 2022. 1. 25.

Neo4j Graph Database

Neo4j는 Neo4j 사가 개발한 그래프 데이터베이스 관리 시스템입니다.

NoSQL의 일종인데, 사용해보면서 느낀점이 일반적인 NoSQL과는 좀 다르다는 점이 눈에 띄었습니다. RDB와 NoSQL 그 중간 어디쯤(?) 이라는 생각이 많이 들었는데요, RDB와 비교하여 여러가지 지원하는 패키지도 많고 DBMS에서 데이터 연산을 빠르게 제공하기 때문에 데이터 과학, 보안 위협 탐지 등의 분야에서 폭 넓게 쓰인다고 합니다.

오늘은 간단하게 Neo4j 를 이용해서 실습을 진행해 보겠습니다.

Neo4j Docker

저는 Docker 를 이용해서 Neo4j 서버를 올리겠습니다.

Docker를 이용하여 아래 커맨드로 Neo4j 이미지를 다운받고 서버를 실행해 보겠습니다.

docker run \\
    --name testneo4j \\
    -p7474:7474 -p7687:7687 \\
    -d \\
    -v $HOME/neo4j/data:/data \\
    -v $HOME/neo4j/logs:/logs \\
    -v $HOME/neo4j/import:/var/lib/neo4j/import \\
    -v $HOME/neo4j/plugins:/plugins \\
    --env NEO4J_AUTH=neo4j/test \\
    neo4j:latest

Docker Desktop 을 이용해서 로그를 확인해 보겠습니다.

아래 로그가 찍히면 성공적으로 실행된 겁니다.

이제 본인의 localhost:7474 로 진입해 보면 아래 화면이 나옵니다.

Neo4j Browser

여기서 ID/PW 인증을 해야하는데, 초기 ID/PW는 neo4j / neo4j 입니다.

접속해 보면 아래와 같은 화면이 나오는데 여기는 neo4j admin 페이지라고 생각하시면 됩니다. 이 페이지에서 여러가지 쿼리를 테스트하고 시각화된 그래프를 확인할 수 있습니다.

Neo4j Query

neo4j 튜토리얼을 통해 상단에 보이는 neo4j Bash에 간단한 쿼리 하나를 입력해보겠습니다.

neo4j$ CREATE (ee:Person {name: 'Emil', from: 'Sweden', kloutScore: 99})

위 쿼리를 실행시키고 좌측 상단에 DB 모양으로 된 아이콘을 클릭하면 쿼리된 데이터를 확인할 수 있습니다.

Node Lables 에 ‘(1)’ ( 은 모든 데이터입니다) 라벨을 눌러서 데이터를 확인해보면

노드 하나가 완성된 것을 볼수가 있습니다! 다시 한번 쿼리를 살펴볼까요?

neo4j$ CREATE (ee: Person {name: 'Emil', from: 'Sweden', kloutScore: 99})

이 쿼리와 위 사진에서 알 수 있는것은 Node 라는 개념과 Property 라는 개념입니다.

Person 이라는 노드 타입이 있고, 저희가 만든 노드는 Person 타입입니다. 쿼리를 살펴보면 ee 라는 변수에 Person 이라는 타입을 할당한 것을 볼 수 있습니다.

그 오른쪽엔 Property를 작성할 수 있습니다.

즉, 쿼리를 풀어보면 노드는 Person 타입으로 생성하고 그 Person 타입 노드의 속성으로 name, from, kloutScore가 들어간 겁니다.

실제로 JSON 형태로 데이터를 확인해 볼 수 있는데 properties 라는 key의 value들을 살펴보면 아래와 같습니다.

이번엔 생성한 데이터를 읽어보겠습니다.

neo4j 에선 READ 역할을 MATCH 라는 키워드를 사용합니다.

똑같이 상단 neo4j Bash를 이용하여 아까 생성한 노드를 READ 해 보겠습니다.

neo4j$ MATCH (ee:Person) WHERE ee.name = 'Emil' RETURN ee;

아까와 같은 출력결과를 보여줍니다. 쿼리는 RDB에 익숙한 사람이 딱 봐도 알아볼 수 있게 쉬운데요, Person 타입을 가진 Node중에 name이 ‘Emil’ 인 데이터를 가져오는 겁니다. 각 노드에 접근은 ‘ee’ 라는 변수를 이용하는 것을 볼 수 있습니다.

이번엔 데이터를 좀 더 많이 추가하고 노드간에 관계를 성립시켜 보겠습니다.

MATCH (ee:Person) WHERE ee.name = 'Emil'
CREATE (js:Person { name: 'Johan', from: 'Sweden', learn: 'surfing' }),
(ir:Person { name: 'Ian', from: 'England', title: 'author' }),
(rvb:Person { name: 'Rik', from: 'Belgium', pet: 'Orval' }),
(ally:Person { name: 'Allison', from: 'California', hobby: 'surfing' }),
(ee)-[:KNOWS {since: 2001}]->(js),(ee)-[:KNOWS {rating: 5}]->(ir),
(js)-[:KNOWS]->(ir),(js)-[:KNOWS]->(rvb),
(ir)-[:KNOWS]->(js),(ir)-[:KNOWS]->(ally),
(rvb)-[:KNOWS]->(ally)

결과는 아래와 같습니다.

갑자기 늘어난 쿼리양에 조금 당황할 법 하지만 알고보면 간단합니다.

맨위에 MATCH 문으로 처음 생성했던 노드를 가져옵니다. 이는 변수 ‘ee’ 가 필요하기 때문입니다.

왜냐하면 추가로 생겨나는 노드와의 관계를 연결할 때 사용되기 때문입니다.

그 아래에 있는 CREATE는 추가 설명이 필요없을 것 같고 그 아래에 있는 관계만 설명하겠습니다.

(ee)-[:KNOWS {since: 2001}]->(js),
(ee)-[:KNOWS {rating: 5}]->(ir),

변수 ee는 맨 위에 MATCH 문에서 가져온, name이 ‘Emil’ 인 노드입니다. 즉 ee는 ‘emil’ 노드입니다.

그 중간에 [:KNOWS] 라는 키워드가 들어가는데, 이는 ‘관계’ 명입니다. 노드간의 연결을 위해선 관계가 필요하죠? 거기서 사용이 되고 :KNOWS 우측에 있는 {since: 2001} 은 관계의 Property 입니다. 노드(Labels) 와 똑같이 속성을 부여할 수 있습니다. 물론 부여하지 않을수도 있습니다.

그리고 [:KNOWS] 양 옆에 (ee)-[:KNOWS]→(js) 처럼 변수, 그리고 ‘-’ 와 ‘→’ 가 붙어있습니다. 이는 (ee) 가 (js)를 가리키게 되고 그 관계를 KNOWS 로 표현한 것입니다.

이를 이용하여 관계를 성립시킬 수 있고 최종적으로 위와 같은 그래프가 나오게 됩니다.

MATCH Patterns

Neo4j 를 이용해서 MATCH 절을 사용할 때는 패턴이 있습니다.

‘Emil’ 값을 가지고 있는 노드와 관계가 있는 노드만 검색해 보겠습니다.

MATCH (ee:Person)-[:KNOWS]->(friends)
WHERE ee.name = 'Emil' RETURN ee, friends

이 쿼리를 분석해보면 ee.name이 ‘Emil’ 이라는 값을 가진 노드와 KNOWS 라는 관계로 이루어진 friends 를 검색합니다. 방향은 ee 변수가 friends 변수를 가리키고 있으니 이는 KNOWS 관계에서 ‘Emil’ 노드가 가리키는 방향입니다. 물론 화살표 방향을 반대로도 할 수 있습니다. 화살표를 없애면(-[:KNOWS]-)양방향 검색도 가능합니다.

그리고 ee(Emil)와 friends(Emil이 가리키는 노드)를 리턴합니다.

결과는 아래와 같습니다.

이렇게 MATCH 절을 이용하여 관계로 이루어진 노드를 검색할 수 있습니다.

Neo4j 는 이번 사이드프로젝트 활동때 사용하기 위해 처음 사용해본 DBMS 인데, 특정 패키지를 Import 해와서 DFS, BFS, 다익스트라 등등 그래프를 이용한 알고리즘을 적용하여 최단 경로를검색할 수 있고, 관계를 이용한 유사도 측정 등 여러가지 기능을 지원합니다.

RDS에 익숙해진 저로서는 상당히 재밌는 경험입니다. 앞으로도 계속 쭉 써볼 예정입니다 🙂

긴글 읽어주셔서 감사합니다 :)

'Back-End' 카테고리의 다른 글

CPU 부하, I/O 부하 파악 방법  (0) 2022.07.10
Forward Proxy, Reverse Proxy의 정의와 차이점  (0) 2022.01.02
traceroute 명령의 동작원리  (0) 2022.01.02
Web Server와 WAS의 차이점  (0) 2020.09.02