이 글은 그래프 데이터베이스 Neo4J 기반 데이터 질의 서비스 개발하는 방법을 간략히 설명한다. Neo4j는 ACID(Atomicity,Consistency,Isolation,Durability)의 모든 속성을 지원하는 완전 트랜잭션을 지원하는 그래프 데이터베이스이다.
Neo4j는 2007년에 노이만 라디칼 시스템즈(Neo Technology)라는 회사에 의해 개발되었다. 그래프 데이터베이스는 관계형 데이터베이스와 달리 데이터를 노드와 엣지(관계)로 구성된 그래프 형태로 저장한다. 이러한 방식은 실제 세계의 복잡한 관계를 모델링하기에 적합하며, 네트워크, 사회 네트워크, 지도 및 추천 시스템 등 다양한 분야에서 유용하게 사용된다. neo4j는 가장 인기 있는 그래프 데이터베이스 중 하나로, 고성능, 확장성 및 질의 언어 지원을 특징으로 한다.
Neo4j는 SNS분석, 지도 위치 기반 서비스, IoT 등 그래프형 데이터 관리에 주로 사용된다.
Neo4j구조는 여러 프로젝트와 프로젝트에 포함된 데이터베이스로 구성된다.
시작하기
다음 링크에서 프로그램 다운로드 후 설치한다.
설치 후, new project 후 add - local DBMS 선택한다. DB 생성 후 Open 하면 다음같이 브라우저 창을 볼 수 있다. 생성 시 입력 암호를 잘 기억한다.
다음과 같이 neo4j$ 에 명령을 입력해 레코드를 생성해 본다.
CREATE (john:Person {name: 'John'})
CREATE (joe:Person {name: 'Joe'})
CREATE (steve:Person {name: 'Steve'})
CREATE (sara:Person {name: 'Sara'})
CREATE (maria:Person {name: 'Maria'})
CREATE (john)-[:FRIEND]->(joe)-[:FRIEND]->(steve)
CREATE (john)-[:FRIEND]->(sara)-[:FRIEND]->(maria)
MATCH (n) RETURN n LIMIT 5
결과는 다음과 같이, 질의한 그래프를 표시해준다. 이전 명령이 아래에 표시된 것을 알 수 있다.
http://127.0.0.1:7474/browser 브라우저로 접속해 본다. 초기 ID/PWD는 neo4j, neo4j이다. 여기서, 데스크탑 프로그램과 동일하게 데이터 관리 가능하다.
그래프 DB와 질의어
그래프 DB는 다음 구성요소를 가진다.
Cypher는 그래프 쿼리 언어이다. 문법은 다음과 같다.
CREATE: 노드, 관계 생성MATCH: 기존 노트, 관계 검색. RETURN이나 WITH로 매칭된 대상 반환.
WHERE: 조건을 지정
MERGE: CREATE와 MATCH를 합친 함수SET: 노드 LABEL과 PROPERTY를 업데이트 함DELETE: 노드, 관계를 삭제
Relation 표현은 다음과 같다.
(node)-[relationship]->(node)
예를 들어, A-[:Knows(since:2020)]->B 경우는 A와 B가 knows 관계가 있으며, since 속성이 2020값을 가진다는 것을 의미한다.
다음은 cypher언어의 기본 형식을 보여준다.
Nodes: ()
Relationships: -[:DIRTECTED]->
Pattern: ()-[]-()
: ()-[]->()
: ()<-[]-()
다음은 이를 이용한 질의 예이다.
MATCH (p:Person)-[:ACTED_IN]->(m:Movie),
(d:Person)-[:DIRECTED]->(m:Movie)
WHERE p.name = 'Tom Hanks' AND p.born = 1956
AND d.name = 'Robert Zemeckis' AND d.born = 1951
RETURN m.title, m.released
파이썬으로 그래프 데이터 관리
이 예에서는 파이썬을 이용해 그래프 데이터를 관리한다. 다음을 설치한다.
pip install neo4j
파이썬에서 드라이버를 설정한다.
from neo4j import GraphDatabase
uri = "bolt://localhost:7687"
username = "neo4j"
password = "neo4jneo4j"
driver = GraphDatabase.driver(uri, auth=(username, password))
session = driver.session()
쿼리를 실행한다.
q = 'MATCH (n) RETURN n LIMIT 5'
nodes = session.run(q)
for node in nodes:
print(node)
query = '''
MERGE (n:Person {name: 'Joe'})
RETURN n
'''
results, summary, keys = driver.execute_query(query, database_='neo4j')
IFC 그래프로 변환
다음은 IFC파일을 그래프 데이터베이스로 변환하는 파이썬 코드이다.
import ifcopenshell, sys, time
from py2neo import Graph, Node
def typeDict(key):
f = ifcopenshell.file()
value = f.create_entity(key).wrapped_data.get_attribute_names()
return value
ifc_path = "input.ifc" # 입력파일
nodes = []
edges = []
# 노드 설정
f = ifcopenshell.open(ifc_path)
for el in f:
if el.is_a() == "IfcOwnerHistory":
continue
tid = el.id()
cls = el.is_a()
pairs = []
keys = []
try:
keys = [x for x in el.get_info() if x not in ["type", "id", "OwnerHistory"]]
except RuntimeError:
pass
for key in keys:
val = el.get_info()[key]
if any(hasattr(val, "is_a") and val.is_a(thisTyp)
for thisTyp in ["IfcBoolean", "IfcLabel", "IfcText", "IfcReal"]):
val = val.wrappedValue
if val and type(val) is tuple and type(val[0]) in (str, bool, float, int):
val = ",".join(str(x) for x in val)
if type(val) not in (str, bool, float, int):
continue
pairs.append((key, val))
nodes.append((tid, cls, pairs))
for i in range(len(el)):
try:
el[i]
except RuntimeError as e:
if str(e) != "Entity not found":
print("ID", tid, e, file=sys.stderr)
continue
if isinstance(el[i], ifcopenshell.entity_instance):
if el[i].is_a() == "IfcOwnerHistory":
continue
if el[i].id() != 0:
edges.append((tid, el[i].id(), typeDict(cls)[i]))
continue
try:
iter(el[i])
except TypeError:
continue
destinations = [x.id() for x in el[i] if isinstance(x, ifcopenshell.entity_instance)]
for connectedTo in destinations:
edges.append((tid, connectedTo, typeDict(cls)[i]))
if len(nodes) == 0:
print("no nodes in file", file=sys.stderr)
sys.exit(1)
# 그래프 데이터베이스 생성
graph = Graph(auth=('neo4j', 'neo4jneo4j')) # http://localhost:7474
graph.delete_all()
for node in nodes:
nId, cls, pairs = node
one_node = Node("IfcNode", ClassName=cls, nid=nId)
for k, v in pairs:
one_node[k] = v
graph.create(one_node)
# graph.run("CREATE INDEX ON :IfcNode(nid)")
print("Node creat prosess done. Take for ", time.time() - start)
print(time.strftime("%Y/%m/%d %H:%M", time.strptime(time.ctime())))
query_rel = """
MATCH (a:IfcNode)
WHERE a.nid = {:d}
MATCH (b:IfcNode)
WHERE b.nid = {:d}
CREATE (a)-[:{:s}]->(b)
"""
for (nId1, nId2, relType) in edges:
graph.run(query_rel.format(nId1, nId2, relType))
생성 결과는 다음과 같다.
MATCH (n1)-[r]->(n2)
WHERE n1.ClassName = "IfcBuildingStorey"
RETURN r, n1, n2;
결론
Neo4j 그래프 데이터베이스는 데이터를 노드와 엣지(관계)로 구성된 그래프 형태로 저장한다. 이러한 방식은 실제 세계의 복잡한 관계를 모델링하기에 적합하며, 네트워크, 사회 네트워크, 지도 및 추천 시스템 등 다양한 분야에서 유용하게 사용된다. 이 글을 통해 그래프 데이터를 질의하고 정보를 생성하는 서비스 개발 방법을 확인해 보았다.
- Implementing GraphReader with Neo4j and LangGraph | by Tomaz Bratanic | Sep, 2024 | Towards Data Science
- Welcome to Neo4j - Getting Started
- This repository includes the IFCWebServer scripts to convert IFC models into Neo4j graph database
- Data model server and online for Building Information Models (BIM) based on IFC standards
- Connecting Neo4j to Building Information Models - Neo4j Graph Platform / Visualization - Neo4j Online Community
- A Graph Database and Query Approach to IFC Data Management.pdf (ufl.edu)
- Application of graph databases and graph theory concepts for advanced analysing of BIM models based on IFC standard (researchgate.net)
- IFCtoLBD converts IFC (Industry Foundation Classes STEP formatted files into the Linked Building Data ontologies. (github.com)
- Implementing Advanced Retrieval RAG Strategies With Neo4j
- Enhancing the Accuracy of RAG Applications With Knowledge Graphs | by Tomaz Bratanic | Neo4j Developer Blog | Medium
- Building RAG Applications With the Neo4j GenAI Stack: A Guide
- Generative AI - Ground LLMs with Knowledge Graphs (neo4j.com)
- Open source IFC library and geometry engine and IfcConvert
- Nobuho/IFC-Neo4j-converter
- RAG (Retrieval Augmented Generation) Demo - Neo4j Labs
- RAG with a Graph database | OpenAI Cookbook
- Cypher4BIM
- Applied Sciences | Free Full-Text | Graph Database and Matrix-Based Intelligent Generation of the Assembly Sequence of Prefabricated Building Components
- Knowledge graph representation method for semantic 3D modeling of Chinese grottoes
- Neo4j Tutorial