약국 POS 시스템의 GraphRAG 기반 추천 시스템 구축 관련 문서:
## 핵심 설계 문서
1. 질병코드기반 제품추천.md
- ICD-10 질병 코드 활용 추천 시스템 설계
- 계층 구조 (질병 → 질병군 → 제품군 → 개별 제품)
- 처방전 기반 추천 알고리즘
2. complex-product-graph-modeling.md
- 복합제(비맥스제트 등) 그래프 모델링
- 성분 간 시너지 효과 표현
- 복합 증상 매칭 쿼리 예시
3. pubmed-graphrag-workflow.md
- PubMed → GraphRAG 전체 워크플로우 (5단계)
- 논문 검색, 근거 추출, 지식 그래프 구축
- MCP Server 개발 가이드
## 그래프 DB 비교 및 평가
4. sqlite-graph-evaluation.md
- SQLite vs SQLite-Graph vs Neo4j 비교
- 현 시점(2026-01) 평가: 기존 SQL 유지 권장
- 6개월 후 재평가 계획
5. opensource-graph-db-comparison.md
- 오픈소스 그래프 DB 비교 (Neo4j, ArangoDB 등)
6. 온톨로지로전환.md
- 관계형 DB → 온톨로지 구조 전환 가이드
- PubMed RAG 활용 방안
- 추론 규칙 설계
## PubMed GraphRAG 활용
7. pycnogenol-multi-indication-graphrag.md
- 피크노제놀 다중 적응증 GraphRAG 구축 사례
- 7가지 적응증별 근거 수준
8. grpahrag_아쉬아간다.md
- Ashwagandha GraphRAG 구축 사례
9. pubdmed이용ai.md
- PubMed + AI 통합 활용 가이드
## 추가 워크플로우
10. pubmed-graphrag-workflow_next.md
- 다음 단계 워크플로우
11. PostgresGRAPH전환.md
- PostgreSQL + Apache AGE 전환 가이드
모든 문서는 한국어로 작성되었으며, 코드 예시는 영어로 포함.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
658 lines
20 KiB
Markdown
658 lines
20 KiB
Markdown
# 오픈소스 그래프 DB 비교 및 추천
|
|
|
|
> Neo4j 대신 사용할 수 있는 오픈소스 그래프 데이터베이스 옵션
|
|
|
|
**작성일**: 2026-01-24
|
|
**대상 프로젝트**: 약국 POS QR 시스템 (PubMed GraphRAG)
|
|
|
|
---
|
|
|
|
## 🎯 평가 기준
|
|
|
|
우리 프로젝트에 필요한 조건:
|
|
```
|
|
✅ 완전한 오픈소스 (상업적 제약 없음)
|
|
✅ Cypher 또는 유사 쿼리 언어 지원
|
|
✅ Python 통합 용이
|
|
✅ 배포 간편 (별도 서버 최소화)
|
|
✅ SQLite/PostgreSQL 같은 익숙한 DB와 통합
|
|
✅ 중소 규모 그래프 최적화 (1,000~10,000 노드)
|
|
```
|
|
|
|
---
|
|
|
|
## 📊 오픈소스 그래프 DB 비교
|
|
|
|
### 1. **Apache AGE** ⭐⭐⭐⭐⭐ 최고 추천!
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ PostgreSQL + 그래프 = Apache AGE │
|
|
│ "기존 PostgreSQL에 그래프 기능 추가" │
|
|
└─────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
#### 🌟 핵심 특징
|
|
- **PostgreSQL 확장** (익숙한 DB + 그래프 기능)
|
|
- **Cypher 쿼리 완벽 지원** (Neo4j와 동일)
|
|
- **SQL + Cypher 혼합 사용 가능**
|
|
- **Apache 2.0 라이선스** (완전 오픈소스)
|
|
- **기존 PostgreSQL 데이터와 그래프 결합 가능**
|
|
|
|
#### ✅ 장점
|
|
```python
|
|
# SQL과 Cypher를 함께 사용!
|
|
# 기존 테이블 (users, products)
|
|
SELECT * FROM users WHERE age > 30;
|
|
|
|
# 그래프 쿼리 (관계 탐색)
|
|
SELECT * FROM cypher('graph_name', $$
|
|
MATCH (u:User)-[:PURCHASED]->(p:Product)
|
|
WHERE u.age > 30
|
|
RETURN u.name, p.name
|
|
$$) AS (user_name text, product_name text);
|
|
```
|
|
|
|
#### ⚠️ 단점
|
|
- PostgreSQL 필요 (SQLite보다 무거움)
|
|
- 비교적 신생 프로젝트 (2020년 시작)
|
|
|
|
#### 📦 설치 (Ubuntu/Debian 예시)
|
|
```bash
|
|
# PostgreSQL 설치
|
|
sudo apt-get install postgresql-14
|
|
|
|
# Apache AGE 설치
|
|
sudo apt-get install postgresql-14-age
|
|
|
|
# 확장 활성화
|
|
CREATE EXTENSION age;
|
|
```
|
|
|
|
#### 🐍 Python 사용
|
|
```python
|
|
import psycopg2
|
|
from age import Age
|
|
|
|
conn = psycopg2.connect(
|
|
host="localhost",
|
|
database="pharmacy_db",
|
|
user="postgres"
|
|
)
|
|
|
|
cursor = conn.cursor()
|
|
|
|
# 그래프 생성
|
|
cursor.execute("""
|
|
SELECT create_graph('pharmacy_graph');
|
|
""")
|
|
|
|
# Cypher 쿼리
|
|
cursor.execute("""
|
|
SELECT * FROM cypher('pharmacy_graph', $$
|
|
CREATE (n:Drug {name: 'Naproxen', type: 'NSAID'})
|
|
RETURN n
|
|
$$) AS (drug agtype);
|
|
""")
|
|
|
|
# 경로 탐색
|
|
cursor.execute("""
|
|
SELECT * FROM cypher('pharmacy_graph', $$
|
|
MATCH path = (d:Drug {name: 'Statin'})-[*1..3]->(s:Symptom)
|
|
RETURN path
|
|
$$) AS (path agtype);
|
|
""")
|
|
```
|
|
|
|
#### 🎯 우리 프로젝트 적용
|
|
```
|
|
현재: SQLite (mileage.db)
|
|
↓
|
|
마이그레이션: PostgreSQL + Apache AGE
|
|
↓
|
|
장점:
|
|
- 기존 users, transactions 테이블 유지 (SQL)
|
|
- 약물-증상 관계는 그래프 (Cypher)
|
|
- 한 DB에서 모두 처리 ✨
|
|
```
|
|
|
|
---
|
|
|
|
### 2. **Memgraph** ⭐⭐⭐⭐
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ 빠른 인메모리 그래프 DB │
|
|
│ "Neo4j와 호환되는 Cypher 지원" │
|
|
└─────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
#### 🌟 핵심 특징
|
|
- **완전한 Cypher 지원** (Neo4j 호환)
|
|
- **인메모리 처리** (매우 빠름)
|
|
- **스트림 처리 지원** (Kafka 통합)
|
|
- **BSL 라이선스** (Community Edition 무료)
|
|
|
|
#### ✅ 장점
|
|
- Neo4j보다 빠름 (인메모리)
|
|
- 완전한 Cypher 지원 (학습 곡선 낮음)
|
|
- Python 라이브러리 우수
|
|
|
|
#### ⚠️ 단점
|
|
- 별도 서버 필요
|
|
- 인메모리 → 메모리 많이 필요
|
|
- 데이터 영속성 설정 필요
|
|
|
|
#### 🐍 Python 사용
|
|
```python
|
|
from gqlalchemy import Memgraph
|
|
|
|
memgraph = Memgraph(host='127.0.0.1', port=7687)
|
|
|
|
# Cypher 쿼리 (Neo4j와 동일)
|
|
results = memgraph.execute_and_fetch("""
|
|
MATCH (d:Drug {name: 'Naproxen'})-[:SAFER_THAN]->(other:Drug)
|
|
RETURN d.name, other.name
|
|
""")
|
|
|
|
for result in results:
|
|
print(result['d.name'], result['other.name'])
|
|
```
|
|
|
|
---
|
|
|
|
### 3. **ArangoDB** ⭐⭐⭐⭐
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ 멀티모델 DB (문서 + 그래프 + 키-밸류) │
|
|
│ "하나의 DB로 모든 데이터 모델 지원" │
|
|
└─────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
#### 🌟 핵심 특징
|
|
- **멀티모델**: 문서(JSON) + 그래프 + 키-밸류
|
|
- **AQL 쿼리 언어** (Cypher와 유사, 더 강력)
|
|
- **완전 오픈소스** (Apache 2.0)
|
|
- **Python, JavaScript 등 다양한 드라이버**
|
|
|
|
#### ✅ 장점
|
|
- 유연함 (그래프 + JSON 문서 모두 저장)
|
|
- 성능 우수
|
|
- 웹 UI 기본 제공
|
|
|
|
#### ⚠️ 단점
|
|
- Cypher 아님 (AQL 학습 필요)
|
|
- 별도 서버 필요
|
|
- 설정 복잡할 수 있음
|
|
|
|
#### 🐍 Python 사용
|
|
```python
|
|
from arango import ArangoClient
|
|
|
|
client = ArangoClient(hosts='http://localhost:8529')
|
|
db = client.db('pharmacy_db', username='root', password='password')
|
|
|
|
# 그래프 생성
|
|
graph = db.create_graph('pharmacy_graph')
|
|
|
|
# 문서 + 그래프 혼합 (강력!)
|
|
result = db.aql.execute("""
|
|
FOR drug IN drugs
|
|
FILTER drug.type == 'NSAID'
|
|
FOR vertex, edge, path IN 1..3 OUTBOUND drug GRAPH 'pharmacy_graph'
|
|
FILTER vertex._id == 'symptoms/pain'
|
|
RETURN path
|
|
""")
|
|
```
|
|
|
|
---
|
|
|
|
### 4. **Dgraph** ⭐⭐⭐
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ GraphQL 네이티브 그래프 DB │
|
|
│ "GraphQL로 그래프 쿼리" │
|
|
└─────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
#### 🌟 핵심 특징
|
|
- **GraphQL 쿼리 언어** (Cypher 대신)
|
|
- **Go로 작성** (빠르고 가벼움)
|
|
- **분산 처리 지원**
|
|
- **Apache 2.0 라이선스**
|
|
|
|
#### ✅ 장점
|
|
- GraphQL 사용 시 최적
|
|
- 성능 우수
|
|
- 분산 확장 용이
|
|
|
|
#### ⚠️ 단점
|
|
- Cypher 미지원 (GraphQL 학습 필요)
|
|
- 별도 서버 필요
|
|
- 커뮤니티 Neo4j보다 작음
|
|
|
|
---
|
|
|
|
### 5. **JanusGraph** ⭐⭐⭐
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ Apache 재단 대규모 그래프 DB │
|
|
│ "수억 개 노드 지원" │
|
|
└─────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
#### 🌟 핵심 특징
|
|
- **Apache 재단 공식 프로젝트**
|
|
- **대규모 그래프 최적화** (수십억 엣지)
|
|
- **Gremlin 쿼리 언어** (Cypher 아님)
|
|
- **다양한 백엔드 지원** (Cassandra, HBase 등)
|
|
|
|
#### ✅ 장점
|
|
- 대규모 그래프에 최적
|
|
- Apache 재단 신뢰성
|
|
- 엔터프라이즈급 기능
|
|
|
|
#### ⚠️ 단점
|
|
- **우리 프로젝트에 과함** (중소 규모용 아님)
|
|
- 설정 매우 복잡
|
|
- Gremlin 학습 곡선 높음
|
|
|
|
---
|
|
|
|
### 6. **Nebula Graph** ⭐⭐⭐
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────┐
|
|
│ 분산 그래프 DB │
|
|
│ "중국발 오픈소스, 빠른 성능" │
|
|
└─────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
#### 🌟 핵심 특징
|
|
- **nGQL** (Cypher와 유사)
|
|
- **분산 아키텍처**
|
|
- **Apache 2.0 라이선스**
|
|
|
|
#### ⚠️ 단점
|
|
- 별도 서버 (Meta, Graph, Storage)
|
|
- 설정 복잡
|
|
- 커뮤니티 주로 중국어
|
|
|
|
---
|
|
|
|
## 🏆 종합 비교표
|
|
|
|
```
|
|
┌─────────────┬──────────┬──────────┬──────────┬──────────┬──────────┐
|
|
│ 항목 │ AGE │ Memgraph │ ArangoDB │ Dgraph │ JanusGrph│
|
|
├─────────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
|
|
│ 쿼리 언어 │ Cypher │ Cypher │ AQL │ GraphQL │ Gremlin │
|
|
├─────────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
|
|
│ 배포 난이도 │ ⭐⭐ │ ⭐⭐⭐ │ ⭐⭐⭐ │ ⭐⭐⭐ │ ⭐⭐⭐⭐⭐│
|
|
├─────────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
|
|
│ 학습 곡선 │ ⭐ │ ⭐ │ ⭐⭐ │ ⭐⭐ │ ⭐⭐⭐⭐ │
|
|
├─────────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
|
|
│ 성능 │ ⭐⭐⭐⭐ │ ⭐⭐⭐⭐⭐│ ⭐⭐⭐⭐ │ ⭐⭐⭐⭐ │ ⭐⭐⭐⭐⭐│
|
|
├─────────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
|
|
│ SQL 통합 │ ✅ │ ❌ │ ❌ │ ❌ │ ❌ │
|
|
├─────────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
|
|
│ 중소규모 적합│ ✅ │ ✅ │ ✅ │ ⭐⭐ │ ❌ │
|
|
├─────────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
|
|
│ 라이선스 │ Apache │ BSL │ Apache │ Apache │ Apache │
|
|
├─────────────┼──────────┼──────────┼──────────┼──────────┼──────────┤
|
|
│ 우리적합도 │⭐⭐⭐⭐⭐│ ⭐⭐⭐⭐ │ ⭐⭐⭐ │ ⭐⭐ │ ⭐ │
|
|
└─────────────┴──────────┴──────────┴──────────┴──────────┴──────────┘
|
|
|
|
⭐ 적음/쉬움/낮음 = 좋음
|
|
⭐⭐⭐⭐⭐ 많음/어려움/높음 = 나쁨 (배포, 학습 곡선)
|
|
⭐⭐⭐⭐⭐ 많음 = 좋음 (성능, 적합도)
|
|
```
|
|
|
|
---
|
|
|
|
## 🎯 우리 프로젝트 최적 선택
|
|
|
|
### 🥇 1순위: **Apache AGE**
|
|
|
|
#### 선택 이유
|
|
```
|
|
✅ PostgreSQL 확장 (익숙한 환경)
|
|
✅ SQL + Cypher 혼합 사용 (마이그레이션 쉬움)
|
|
✅ 기존 데이터 + 그래프 한 DB에서 관리
|
|
✅ 완전 오픈소스 (Apache 2.0)
|
|
✅ 배포 간단 (PostgreSQL만 있으면 됨)
|
|
```
|
|
|
|
#### 마이그레이션 경로
|
|
```
|
|
현재: SQLite
|
|
↓
|
|
1단계: PostgreSQL + 기본 테이블 마이그레이션
|
|
↓
|
|
2단계: Apache AGE 확장 설치
|
|
↓
|
|
3단계: 그래프 노드/엣지 생성
|
|
↓
|
|
결과: SQL (users, transactions) + Cypher (약물 관계)
|
|
```
|
|
|
|
---
|
|
|
|
### 🥈 2순위: **Memgraph**
|
|
|
|
#### 선택 이유
|
|
```
|
|
✅ 완전한 Cypher 지원 (Neo4j 호환)
|
|
✅ 매우 빠름 (인메모리)
|
|
✅ Python 라이브러리 우수
|
|
```
|
|
|
|
#### 적합한 경우
|
|
```
|
|
- 실시간 추천이 매우 중요
|
|
- 메모리 충분히 있음
|
|
- 별도 서버 운영 가능
|
|
```
|
|
|
|
---
|
|
|
|
### 🥉 3순위: **ArangoDB**
|
|
|
|
#### 선택 이유
|
|
```
|
|
✅ 멀티모델 (유연함)
|
|
✅ 성능 우수
|
|
✅ 웹 UI 좋음
|
|
```
|
|
|
|
#### 적합한 경우
|
|
```
|
|
- JSON 문서 + 그래프 모두 필요
|
|
- AQL 학습 가능
|
|
- 다양한 데이터 모델 실험
|
|
```
|
|
|
|
---
|
|
|
|
## 🛠️ Apache AGE 실전 적용 가이드
|
|
|
|
### 1. 설치 (Docker 사용)
|
|
|
|
```bash
|
|
# Docker Compose 설정
|
|
# docker-compose.yml
|
|
version: '3.8'
|
|
services:
|
|
postgres-age:
|
|
image: apache/age:latest
|
|
environment:
|
|
POSTGRES_USER: postgres
|
|
POSTGRES_PASSWORD: password
|
|
POSTGRES_DB: pharmacy_db
|
|
ports:
|
|
- "5432:5432"
|
|
volumes:
|
|
- pgdata:/var/lib/postgresql/data
|
|
|
|
volumes:
|
|
pgdata:
|
|
```
|
|
|
|
```bash
|
|
# 실행
|
|
docker-compose up -d
|
|
```
|
|
|
|
### 2. Python 통합
|
|
|
|
```python
|
|
"""
|
|
Apache AGE + Python 예시
|
|
"""
|
|
import psycopg2
|
|
from age import Age
|
|
|
|
# 연결
|
|
conn = psycopg2.connect(
|
|
host="localhost",
|
|
database="pharmacy_db",
|
|
user="postgres",
|
|
password="password"
|
|
)
|
|
|
|
age = Age(conn)
|
|
cursor = conn.cursor()
|
|
|
|
# 1. 그래프 생성
|
|
age.setGraph('pharmacy_graph')
|
|
cursor.execute("SELECT create_graph('pharmacy_graph');")
|
|
|
|
# 2. 노드 생성 (Cypher)
|
|
cursor.execute("""
|
|
SELECT * FROM cypher('pharmacy_graph', $$
|
|
CREATE (statin:Drug {name: 'Statin', type: 'HMG-CoA inhibitor'}),
|
|
(coq10:Drug {name: 'CoQ10', type: 'Supplement'}),
|
|
(myopathy:Condition {name: 'Myopathy'}),
|
|
(evidence:Evidence {pmid: '30371340', reliability: 0.95})
|
|
RETURN statin, coq10, myopathy, evidence
|
|
$$) AS (statin agtype, coq10 agtype, myopathy agtype, evidence agtype);
|
|
""")
|
|
|
|
# 3. 관계 생성
|
|
cursor.execute("""
|
|
SELECT * FROM cypher('pharmacy_graph', $$
|
|
MATCH (statin:Drug {name: 'Statin'}),
|
|
(coq10:Drug {name: 'CoQ10'}),
|
|
(myopathy:Condition {name: 'Myopathy'}),
|
|
(evidence:Evidence {pmid: '30371340'})
|
|
CREATE (statin)-[:INHIBITS {mechanism: 'HMG-CoA pathway'}]->(coq10),
|
|
(coq10)-[:REDUCES {effect_size: -1.60, p_value: 0.001}]->(myopathy),
|
|
(evidence)-[:SUPPORTS]->(coq10)-[:REDUCES]->(myopathy)
|
|
RETURN statin, coq10, myopathy
|
|
$$) AS (statin agtype, coq10 agtype, myopathy agtype);
|
|
""")
|
|
|
|
# 4. 경로 탐색 (GraphRAG!)
|
|
cursor.execute("""
|
|
SELECT * FROM cypher('pharmacy_graph', $$
|
|
MATCH path = (statin:Drug {name: 'Statin'})-[*1..3]->(myopathy:Condition {name: 'Myopathy'})
|
|
RETURN path
|
|
$$) AS (path agtype);
|
|
""")
|
|
|
|
results = cursor.fetchall()
|
|
for row in results:
|
|
print(row[0])
|
|
|
|
# 5. SQL + Cypher 혼합!
|
|
cursor.execute("""
|
|
-- SQL: 사용자 조회
|
|
WITH high_risk_users AS (
|
|
SELECT id, name, age
|
|
FROM users
|
|
WHERE age > 60 AND has_hypertension = true
|
|
)
|
|
-- Cypher: 안전한 약물 추천
|
|
SELECT u.name, drug_name
|
|
FROM high_risk_users u,
|
|
LATERAL (
|
|
SELECT * FROM cypher('pharmacy_graph', $$
|
|
MATCH (drug:Drug)-[:SAFE_FOR]->(profile:PatientProfile {name: 'Elderly_HTN'})
|
|
RETURN drug.name
|
|
$$) AS (drug_name agtype)
|
|
);
|
|
""")
|
|
|
|
conn.commit()
|
|
conn.close()
|
|
```
|
|
|
|
### 3. 실제 추천 시스템 예시
|
|
|
|
```python
|
|
"""
|
|
Apache AGE 기반 약물 추천 시스템
|
|
"""
|
|
|
|
class DrugRecommender:
|
|
def __init__(self, conn):
|
|
self.conn = conn
|
|
self.cursor = conn.cursor()
|
|
|
|
def recommend(self, patient_id, symptom):
|
|
"""
|
|
환자 프로필 + 증상 → 약물 추천 (근거 포함)
|
|
"""
|
|
# 1. SQL: 환자 정보 조회
|
|
self.cursor.execute("""
|
|
SELECT age, hypertension, diabetes
|
|
FROM users
|
|
WHERE id = %s
|
|
""", (patient_id,))
|
|
|
|
patient = self.cursor.fetchone()
|
|
age, has_htn, has_dm = patient
|
|
|
|
# 2. 환자 프로필 결정
|
|
if has_htn and has_dm:
|
|
profile = 'Patient_HTN_DM'
|
|
elif has_htn:
|
|
profile = 'Patient_HTN'
|
|
elif age > 65:
|
|
profile = 'Elderly'
|
|
else:
|
|
profile = 'General'
|
|
|
|
# 3. Cypher: 그래프 기반 추천
|
|
self.cursor.execute(f"""
|
|
SELECT * FROM cypher('pharmacy_graph', $$
|
|
MATCH (drug:Drug)-[treats:TREATS]->(condition:Condition {{name: '{symptom}'}})
|
|
WHERE NOT (drug)-[:CONTRAINDICATED_IN]->(:PatientProfile {{name: '{profile}'}})
|
|
MATCH (evidence:Evidence)-[:SUPPORTS]->(treats)
|
|
RETURN
|
|
drug.name AS drug,
|
|
treats.effect_size AS effect,
|
|
evidence.pmid AS pmid,
|
|
evidence.reliability AS reliability
|
|
ORDER BY evidence.reliability DESC, treats.effect_size DESC
|
|
LIMIT 1
|
|
$$) AS (drug agtype, effect agtype, pmid agtype, reliability agtype);
|
|
""")
|
|
|
|
result = self.cursor.fetchone()
|
|
|
|
if result:
|
|
return {
|
|
'drug': result[0],
|
|
'effect_size': result[1],
|
|
'evidence_pmid': result[2],
|
|
'reliability': result[3],
|
|
'patient_profile': profile
|
|
}
|
|
else:
|
|
return None
|
|
|
|
|
|
# 사용 예시
|
|
recommender = DrugRecommender(conn)
|
|
|
|
# 환자 ID 123, 증상 "Pain"
|
|
recommendation = recommender.recommend(patient_id=123, symptom='Pain')
|
|
|
|
print(recommendation)
|
|
# {
|
|
# 'drug': 'Naproxen',
|
|
# 'effect_size': -1.8,
|
|
# 'evidence_pmid': '27959716',
|
|
# 'reliability': 0.99,
|
|
# 'patient_profile': 'Patient_HTN_DM'
|
|
# }
|
|
```
|
|
|
|
---
|
|
|
|
## 📊 마이그레이션 로드맵
|
|
|
|
### Phase 1: SQLite → PostgreSQL (1주)
|
|
```sql
|
|
-- 기존 SQLite 테이블 PostgreSQL로 이동
|
|
-- users, transactions, mileage_ledger 등
|
|
```
|
|
|
|
### Phase 2: Apache AGE 설치 (1일)
|
|
```bash
|
|
CREATE EXTENSION age;
|
|
SELECT create_graph('pharmacy_graph');
|
|
```
|
|
|
|
### Phase 3: 그래프 데이터 생성 (1주)
|
|
```python
|
|
# PubMed 논문 → 그래프 트리플
|
|
# Cypher CREATE 문으로 노드/엣지 생성
|
|
```
|
|
|
|
### Phase 4: 추천 시스템 업그레이드 (1주)
|
|
```python
|
|
# SQL + Cypher 혼합 쿼리
|
|
# GraphRAG 추론 경로 자동 생성
|
|
```
|
|
|
|
---
|
|
|
|
## 🎯 최종 권장사항
|
|
|
|
### ✅ **즉시 도입 가능: Apache AGE**
|
|
|
|
**선택 이유**:
|
|
1. PostgreSQL 확장 (익숙함)
|
|
2. SQL + Cypher 모두 사용 가능
|
|
3. 기존 데이터 + 그래프 한 DB
|
|
4. 완전 오픈소스
|
|
5. 마이그레이션 쉬움
|
|
|
|
**시작 단계**:
|
|
```bash
|
|
# 1. Docker로 테스트
|
|
docker run -p 5432:5432 apache/age
|
|
|
|
# 2. Python 라이브러리 설치
|
|
pip install psycopg2-binary age
|
|
|
|
# 3. 간단한 그래프 생성 테스트
|
|
python test_age.py
|
|
```
|
|
|
|
---
|
|
|
|
### 🔮 **대안: Memgraph** (성능 최우선 시)
|
|
|
|
**조건**:
|
|
- 별도 서버 운영 가능
|
|
- 메모리 충분 (8GB+)
|
|
- 실시간 추천 필수
|
|
|
|
---
|
|
|
|
## 📚 참고 링크
|
|
|
|
- **Apache AGE**: https://age.apache.org/
|
|
- GitHub: https://github.com/apache/age
|
|
- 문서: https://age.apache.org/age-manual/master/index.html
|
|
|
|
- **Memgraph**: https://memgraph.com/
|
|
- 문서: https://memgraph.com/docs
|
|
|
|
- **ArangoDB**: https://www.arangodb.com/
|
|
- 문서: https://www.arangodb.com/docs/
|
|
|
|
- **Dgraph**: https://dgraph.io/
|
|
- GitHub: https://github.com/dgraph-io/dgraph
|
|
|
|
---
|
|
|
|
**작성**: 2026-01-24
|
|
**추천**: Apache AGE ⭐⭐⭐⭐⭐
|