Hodustory/프로그래밍&DB

Neo4j 이용하기

호두밥 2018. 3. 8. 14:37


Neo4j 그래프 데이터베이스 & 사이퍼

Neo4j는 그래프 데이터베이스 도구 중 하나이며, 사이퍼라는 쿼리 언어를 이용합니다.

Neo4j model.JPG

기본 데이터 구조는 위의 그림과 같습니다. 노드(개체)와 관계, 노드와 관계에 대한 속성, 노드를 묶는 단위는 라벨로 이루어져 있죠.

매뉴얼을 보면 다음과 같이 설명합니다.


 노드Nodes

  관계Relationships

데이터 개체

Nodes are the main data elements

관계로 다른 노드들과 연결

Nodes are connected to other nodes via relationships

하나 이상의 속성을 지님

Nodes can have one or more properties (i.e., attributes stored as key/value pairs)

하나 이상의 라벨을 지님

Nodes have one or more labels that describes its role in the graph

두 개의 노드를 연결

Relationships connect two nodes

직접적으로 연결

Relationships are directional

하나의 노드가 여러 개의 관계, 재귀적인 관계도 가질 수 있음

Nodes can have multiple, even recursive relationships

관계는 하나 이상의 속성을 가진다

Relationships can have one or more properties (i.e., attributes stored as key/value pairs)

  속성Properties

  라벨Labels

문자로 정의된 값

Properties are named values where the name (or key) is a string

색인화되고, 제한될 수 있다.

Properties can be indexed and constrained

다양한 속성으로 복합적인 색인을 만들 수 있다

Composite indexes can be created from multiple properties


노드를 묶는 단위

Labels are used to group nodes into sets

하나의 노드는 여러개의 라벨을 가질 수 있다

A node may have multiple labels

그래프에서 노드를 더 잘 찾을 수 있도록 색인화된다

Labels are indexed to accelerate finding nodes in the graph

기초 라벨 색인은 속도에 최적화되어 있다

Native label indexes are optimized for speed


다음은 Neo4j에서 데이터를 검색/조작하기 위해 필요한 언어인 'Cyper'에 대해서 알아볼게요. 
기본 문법? 이랄까요. 기본 구조는 아래의 그림과 같습니다.
Cypher model.JPG
Cyper를 사용하기 위해 가장 먼저 이해해야 될 개념은 '변수'라는 것입니다. 변수랑 특정 관계나 값 등을 가진 임의의 값! 말 그대로 지정된 조건을 가진, 변화하는 값입니다. 미지수 x를 떠올리면 쉬울듯 싶어요. 이런 변수는 불필요한 코드의 반복을 피하기 위해 사이퍼 뿐 아니라 다양한 코딩언어에서 사용됩니다. 사이퍼에서 변수를 표현하는 방식 중 가장 대표적인 두가지를 가져와 봤습니다.

 ( 변수 : 라벨 { 속성 : 속성값 } )
변수 = (노드) - [관계] -> (노드)

변수를 설정하고 그 뒤에 라벨(개체의 그룹)을 적습니다. 특정 속성 값을 지닌 것을 개체를 보고 싶다면 ' { } ' 안에 속성의 이름과 특정 속성 값을 적어주면 됩니다. 개체 뿐 아니라 특정 관계도 변수로 지정될 수 있습니다. 관계는 아래와 같이 표현합니다.

- [ 변수: 관계 {속성: "속성값"} ] -

              • A -[:Knows]-> B : Knows 관계를 가진 A와 B
              • A -[*]-> B : 관계를 가진 A와 B
              • A --> B : 관계를 가진 A와 B
              • A -[*1..3]-> B : 1~3의 거리를 가진 A와 B
              • A -[:Knows*1..3]-> B : Knows관계의 거리가 1~3인 A와 B
              • A -[:Knows{since:2009}]-> B : Knows관계를 가지고 since 속성이 2009값을 가지는 A와 B


다음은 원하는 조건의 데이터를 검색할 때 쓰는 단어인 MATCH를 살펴볼까요. 아래와 같은 형태로 사용합니다.

 MATCH <pattern> WHERE <conditions> RETURN <expression>

Where는 조건을 지정하기 위해 사용되는 단어인데요. >,<,=, in, starts with, ends with, contains  등과 같은 연산자도 사용할 수 있습니다.

              • Where A.name="ooo": name 속성의 값이 ooo인 노드 A
              • Where A.name in ["aaa", "bbb", "ccc"]: name 속성이 값이 aaa, bbb, ccc 중 하나의 값을 가지는 노드 A
              • Where A.name starts with "A": name 속성의 값이 A로 시작하는 노드 A (SQL의 where name like 'A%')
              • Where A.name ends with "A": name 속성의 값이 A로 끝나는 노드 A (SQL의 where name like '%A')
              • Where A.name contains "A": name 속성의 값에 A가 들어가는 노드 A (SQL의 where name like '%A%')


RETURN은 보고 싶은 형태를 지정해줄 때 쓰는 단어입니다. 앞서 검색한 것들은 모두 보고 싶다거나, 검색된 개체 중 특정 속성만 보고 싶다거나, 검색된 개체의 개수를 보고 싶다거나 할 때 말이죠. 이 부분은 뒤의 예시문에서 확인해보시면 될 것 같아요.


그리고 데이터 자체를 생성 및 삭제를 할 수 있는 단어인 CREATE와 DELETE/ 노드를 수정하는 단어인 SET과 REMOVE는.. 간단히 예시문으로 보여드릴게요. 


CREATE

CREATE (ee:Person { name: "Emil", from: "Sweden", klout: 99 })

CREATE (js:Person { name: "Johan", from: "Sweden", learn: "surfing" }), (ir:Person { name: "Ian", from: "England", title: "author" }), (js)-[:KNOWS {since: 2001}]->(ir)
DELETE
MATCH (A:Person) WHERE A.id="0000" DELETE A
MATCH (n { name: 'Andres' })-[r:KNOWS]->() DELETE r
SET/REMOVE
MATCH (n { name: 'Andres' }) SET n.position = 'Developer', n.surname = 'Taylor'
MATCH (n { name: 'Peter' }) REMOVE n:German RETURN n

다음은 합집합을 표현할 때 쓰이는 UNION과 정렬이 순서를 정하는 ORDER BY를 살펴볼게요.

Union : 합집합 / join
MATCH (n:Actor) RETURN n.name UNION MATCH (n:Movie) RETURN n.title 
Order by : 보여줄 차순, 기본값 오름차순/ desc : 내림차순
MATCH (n:Actor) RETURN n.name, n.age ORDER BY n.age DESC

사이퍼에는 합계와 최대값, 최소값, 존재 여부 등을 보여주는 함수 기능을 지원합니다. 엑셀의 함수를 생각하시면 될 것 같네요.
아래에서 설명하는 것보다 훨씬 많은 기능이 있으니 여기를 참고해주세요.

함수명기능설명사용예시
collect()특정 조건으로 노드를 그룹화하고 그 한 그룹에 속하는 노드의 목록을 보여줌.MATCH (n:person) RETURN collect(n.sex), n.name
count()노드의 갯수, (SQL의 count)MATCH (n:person) return n.sex ,count(n)
exist()()안의 특정 값이 있는 경우 (SQL의 where is not null)MATCH (p:Person) WHERE exists(p.firstname) RETURN p
none()()안의 특정 값이 없는 경우 (SQL의 where is null)MATCH (p:Person) WHERE none(p.firstname) RETURN p
min(), max(), sum()()안의 값의 최소값, 최대값, 합계
length()노드와 노드 사이의 거리
(관계를 정의할때 *를 적어주어야 함. 그렇지 않으면 length의 값이 모두 1로 나옴(관계정의의 기본 단계값이 1이기 때문에 여러 단계의 관계를 보고 싶을때는 *를 써줌).
MATCH P=(A:Person) -[:Knows*]-> (B:Person) RETURN length(P)
shortestPath()노드와 노드 사이의 가장 빠른 길MATCH P=shortestPath((A:Person{name:'AA'}) -[*]-> (B:Person{name:'BB'})) RETURN P


Written by 호두



반응형