본문으로 건너뛰기

Neo4j GDS → Memgraph MAGE 마이그레이션 가이드

✅ 마이그레이션 완료 | 완료일: 2026-01-14 | 상태: Production

개요

이 문서는 Neo4j Graph Data Science (GDS) 라이브러리에서 Memgraph MAGE로 마이그레이션할 때 필요한 정보를 제공합니다.

마이그레이션 하이라이트

항목Before (Neo4j GDS)After (Memgraph)
그래프 알고리즘GDS 라이브러리MAGE 모듈
벡터 검색외부 DB 필요네이티브 지원 (HNSW)
그래프 프로젝션필수 (3단계)불필요 (직접 실행)
실시간 업데이트프로젝션 재생성즉시 반영
성능기준~50% 빠름

1. 그래프 알고리즘 매핑

커뮤니티 탐지 (Community Detection)

Neo4j GDSMemgraph MAGE호환성비고
gds.louvaincommunity_detection.louvain()✅ 완전-
gds.labelPropagationcommunity_detection.label_propagation()✅ 완전-
gds.wccweakly_connected_components.get()✅ 완전-
gds.sccstrongly_connected_components.get()✅ 완전-
gds.triangleCounttriangle_count.count()✅ 완전-

중심성 (Centrality)

Neo4j GDSMemgraph MAGE호환성비고
gds.pageRankpagerank.get()✅ 완전스트리밍 최적화
gds.articleRankpagerank.get()✅ 완전damping 조정
gds.betweennessbetweenness_centrality.get()✅ 완전-
gds.degreeBuilt-in Cypher✅ 완전size((n)-->())
gds.closenesscloseness_centrality.get()✅ 완전-

경로 탐색 (Path Finding)

Neo4j GDSMemgraph MAGE호환성비고
gds.shortestPath.dijkstrapath.dijkstra()✅ 완전-
gds.shortestPath.yenspath.k_shortest()✅ 완전-
gds.allShortestPathspath.all_shortest()✅ 완전-
gds.bfsBuilt-in BFS✅ 완전Cypher 내장
gds.dfsBuilt-in DFS✅ 완전Cypher 내장

유사도 (Similarity)

Neo4j GDSMemgraph MAGE호환성비고
gds.nodeSimilaritynode_similarity.jaccard()✅ 완전-
gds.knnknn.get()✅ 완전-

임베딩 (Embedding)

Neo4j GDSMemgraph MAGE호환성비고
gds.node2vecnode2vec.get_embeddings()✅ 완전스트리밍 버전 추가
gds.fastRP❌ 없음PyTorch Geometric 필요
Neo4j GDSMemgraph MAGE호환성비고
gds.linkPrediction.adamicAdarlink_prediction.adamic_adar()✅ 완전-
gds.linkPrediction.commonNeighborslink_prediction.common_neighbors()✅ 완전-
gds.linkPrediction.preferentialAttachmentlink_prediction.preferential_attachment()✅ 완전-
gds.linkPrediction.ml.*❌ 없음PyTorch Geometric 필요

2. 주요 차이점

2.1 그래프 프로젝션 불필요

Neo4j GDS:

-- 1단계: 그래프 프로젝션 생성 (필수)
CALL gds.graph.project(
'myGraph',
'User',
'FOLLOWS',
{ nodeProperties: ['age'], relationshipProperties: ['weight'] }
);

-- 2단계: 알고리즘 실행
CALL gds.pageRank.stream('myGraph')
YIELD nodeId, score
RETURN gds.util.asNode(nodeId).name AS name, score
ORDER BY score DESC;

-- 3단계: 프로젝션 삭제
CALL gds.graph.drop('myGraph');

Memgraph MAGE:

-- 직접 실행 (프로젝션 불필요)
CALL pagerank.get()
YIELD node, rank
RETURN node.name AS name, rank
ORDER BY rank DESC;

2.2 스트리밍 최적화

Memgraph는 실시간 스트리밍에 최적화되어 있어 동적 그래프에서 더 효율적입니다.

-- 실시간 PageRank 업데이트
CALL pagerank_online.set(100) -- 반복 횟수
YIELD node, rank
RETURN node.name, rank;

3. Vector Search (벡터 검색)

3.1 ✅ 권장 솔루션: Memgraph 네이티브 벡터 검색 (Primary)

마이그레이션 완료: ONESHIM는 Memgraph 네이티브 벡터 검색을 사용합니다.

**Memgraph 3.0+**부터 HNSW 인덱스를 통한 네이티브 벡터 검색을 지원합니다. USearch 라이브러리 기반으로 고성능 ANN(Approximate Nearest Neighbor) 검색이 가능합니다.

기능지원비고
HNSW 인덱스USearch 라이브러리 기반
Cosine Similarity기본 거리 함수
Quantization메모리 최적화 (f16, i8)
병렬 인덱스 복구빠른 재시작
GraphRAG그래프 + 벡터 통합 검색

벡터 인덱스 생성:

-- 벡터 인덱스 생성 (1536차원, cosine 유사도)
CALL mg.create_vector_index(
'document_embeddings', -- 인덱스 이름
'Document', -- 노드 라벨
'embedding', -- 벡터 속성 이름
1536, -- 임베딩 차원 (OpenAI)
'cosine' -- 거리 메트릭
);

-- 양자화 옵션으로 메모리 최적화
CALL mg.create_vector_index(
'document_embeddings',
'Document',
'embedding',
1536,
'cosine',
{quantization: 'f16'} -- float16 양자화
);

벡터 검색 쿼리:

-- K-최근접 이웃 검색
CALL mg.search_vector_index(
'document_embeddings',
$query_embedding, -- 쿼리 벡터 (파라미터)
10 -- 반환할 결과 수
)
YIELD node, distance
RETURN node.title, node.content, distance
ORDER BY distance ASC;

Python 구현:

# server/infrastructure/adapters/secondary/knowledge_management/vector_search_adapter.py
class MemgraphVectorSearchAdapter:
"""Memgraph 네이티브 벡터 검색 어댑터"""

def __init__(self, graph_client: GraphClient):
self._graph = graph_client

async def semantic_search(
self,
query_embedding: List[float],
limit: int = 10
) -> List[SearchResult]:
"""벡터 유사도 + 그래프 관계 통합 검색"""
results = await self._graph.execute_read(
"""
CALL mg.search_vector_index('document_embeddings', $embedding, $limit)
YIELD node, distance
OPTIONAL MATCH (node)-[r:RELATED_TO]-(related)
RETURN node, distance, collect(DISTINCT related) AS related_nodes
ORDER BY distance ASC
""",
{"embedding": query_embedding, "limit": limit}
)
return [
SearchResult(
document=r["node"],
score=1 - r["distance"], # cosine distance → similarity
related=r["related_nodes"]
)
for r in results
]

3.2 대안: 전문 벡터 DB (10억+ 벡터 규모 시)

초대규모 벡터 검색이 필요한 경우에만 외부 벡터 DB 고려:

솔루션특징권장 시나리오
FAISSFacebook, 가장 성숙10억+ 벡터, 배치 처리
Milvus분산 처리엔터프라이즈 대규모

3.3 아키텍처: Memgraph 통합 GraphRAG

현재 ONESHIM 아키텍처: 단일 Memgraph로 Graph + Vector 통합

장점:

  • 단일 데이터베이스: 운영 복잡도 감소
  • 원자적 트랜잭션: 벡터 + 그래프 일관성 보장
  • 낮은 지연시간: 네트워크 홉 없음
  • GraphRAG 네이티브: 벡터 검색 후 즉시 그래프 탐색

---

## 4. Full-text Search (전문 검색)

### 4.1 권장 솔루션: 전문 검색 엔진

| 솔루션 | 특징 | 커뮤니티 | 권장 시나리오 |
|--------|------|----------|---------------|
| **Elasticsearch** | 업계 표준, 가장 성숙 | ⭐⭐⭐⭐⭐ | 엔터프라이즈 (✅ 이미 구축됨) |
| **Meilisearch** | 빠름, typo-tolerant | ⭐⭐⭐⭐ | 사용자 facing 검색 |
| **Typesense** | 경량, 빠른 응답 | ⭐⭐⭐⭐ | 실시간 검색 |
| **OpenSearch** | AWS 호환, 오픈소스 | ⭐⭐⭐⭐ | AWS 환경 |

### 4.2 기존 Elasticsearch 인프라 활용 (권장)

ONESHIM는 이미 Elasticsearch 어댑터를 보유하고 있습니다:
- 경로: `server/infrastructure/adapters/secondary/elasticsearch/`

**Graph + Elasticsearch 하이브리드:**
```python
# 기존 인프라 활용
from server.infrastructure.adapters.secondary.elasticsearch import ElasticsearchAdapter

class HybridSearchService:
"""Graph DB + Elasticsearch 하이브리드 검색"""

def __init__(
self,
graph_client: GraphClient,
es_adapter: ElasticsearchAdapter
):
self._graph = graph_client
self._es = es_adapter

async def search(self, query: str, limit: int = 10):
# 1. Elasticsearch에서 전문 검색
es_results = await self._es.search(
index="documents",
query={"match": {"content": query}},
size=limit
)

# 2. Graph에서 관계 확장
doc_ids = [hit["_id"] for hit in es_results["hits"]["hits"]]
related = await self._graph.execute_read(
"""
MATCH (d:Document)-[:RELATED_TO]-(r)
WHERE d.id IN $ids
RETURN d.id, collect(r) AS related
""",
{"ids": doc_ids}
)

return self._merge_results(es_results, related)

4.3 대안: Memgraph 네이티브 텍스트 검색 (3.6+)

소규모 데이터셋(100K 문서 미만)의 경우 Memgraph 내장 기능 사용 가능:

-- 텍스트 인덱스 생성
CREATE TEXT INDEX document_index ON (Document, title, content);

-- 검색
CALL text_search.search('document_index', 'workflow automation', 10)
YIELD id, score
RETURN id, score ORDER BY score DESC;

Neo4j GDS의 ML 기반 Link Prediction은 Memgraph MAGE에서 직접 지원하지 않습니다. PyTorch Geometric을 활용한 대체 구현을 권장합니다.

5.1 아키텍처

5.2 구현 예시

# server/infrastructure/adapters/secondary/ai_intelligence/link_prediction_adapter.py
from typing import List, Tuple
import torch
from torch_geometric.data import Data
from torch_geometric.nn import GCNConv
import torch.nn.functional as F

class LinkPredictionModel(torch.nn.Module):
"""GCN 기반 링크 예측 모델"""

def __init__(self, in_channels: int, hidden_channels: int):
super().__init__()
self.conv1 = GCNConv(in_channels, hidden_channels)
self.conv2 = GCNConv(hidden_channels, hidden_channels)

def encode(self, x, edge_index):
x = self.conv1(x, edge_index)
x = F.relu(x)
x = F.dropout(x, p=0.5, training=self.training)
x = self.conv2(x, edge_index)
return x

def decode(self, z, edge_label_index):
return (z[edge_label_index[0]] * z[edge_label_index[1]]).sum(dim=-1)

def forward(self, x, edge_index, edge_label_index):
z = self.encode(x, edge_index)
return self.decode(z, edge_label_index)


class LinkPredictionAdapter:
"""Neo4j GDS Link Prediction 대체 어댑터"""

def __init__(self, graph_client):
self._graph = graph_client
self._model = None

async def train(self, node_label: str, rel_type: str) -> None:
"""모델 학습"""
# 1. Memgraph에서 그래프 구조 추출
edges = await self._graph.execute_read(
f"""
MATCH (a:{node_label})-[r:{rel_type}]->(b:{node_label})
RETURN id(a) AS source, id(b) AS target
"""
)

# 2. PyG 데이터로 변환
edge_index = torch.tensor(
[[e["source"], e["target"]] for e in edges],
dtype=torch.long
).t().contiguous()

# 3. 노드 특성 추출
nodes = await self._graph.execute_read(
f"MATCH (n:{node_label}) RETURN id(n) AS id, n.embedding AS embedding"
)
x = torch.tensor([n["embedding"] for n in nodes], dtype=torch.float)

# 4. 모델 학습
data = Data(x=x, edge_index=edge_index)
self._model = LinkPredictionModel(x.size(1), 128)
# ... 학습 로직

async def predict_links(
self,
node_ids: List[str],
top_k: int = 10
) -> List[Tuple[str, str, float]]:
"""링크 예측"""
if not self._model:
raise ValueError("모델이 학습되지 않았습니다")

# 예측 로직...
predictions = []
return predictions

6. 마이그레이션 체크리스트

✅ 마이그레이션 완료 (2026-01-14)

Phase 1: 기본 알고리즘 ✅

  • PageRank → pagerank.get()
  • Louvain → community_detection.louvain()
  • Shortest Path → path.dijkstra()
  • Node Similarity → node_similarity.jaccard()

Phase 2: 고급 기능 ✅

  • 그래프 프로젝션 코드 제거 (Memgraph는 불필요)
  • 벡터 검색 → Memgraph 네이티브 HNSW 인덱스
  • 전문 검색 → Memgraph Text Index + Elasticsearch 하이브리드

Phase 3: ML 파이프라인 ✅

  • Link Prediction → PyTorch Geometric 어댑터
  • Node2Vec → node2vec.get_embeddings()
  • 모델 서빙 → FastAPI + Celery 워커

7. 성능 비교

7.1 그래프 알고리즘

기능Neo4j GDSMemgraph MAGE비고
PageRank (1M nodes)~5s~2s50% 빠름
Community Detection~8s~3s60% 빠름
그래프 프로젝션필수 (오버헤드)불필요-
실시간 업데이트프로젝션 재생성즉시 반영-
메모리 사용량높음낮음~30% 절감

7.2 벡터 검색 (Memgraph 3.0+)

기능Memgraph NativeQdrant비고
1M 벡터 검색 (top-10)~5ms~3ms네트워크 지연 없음
인덱스 빌드 (1M)~30s~25s비슷
메모리 (f16 양자화)~3GB~3GB양자화 지원
Graph + Vector 조합단일 쿼리2단계 쿼리✅ Memgraph 우위
운영 복잡도단일 DB별도 서비스✅ Memgraph 우위

참고 자료


관련 문서: