1. Graph DB의 장점 (vs RDB)
- 기본 특성 비교
항목 | RDB | Graph DB | 의료데이터 관련 예시 |
데이터 모델 | 테이블, 행, 열 구조 | 노드, 관계, 속성 | 환자(노드)-진단(관계)-질병(노드) |
관계 표현 | 외래키를 통한 테이블 간 연결 | 직접적인 관계로 연결 | 약물 상호작용 네트워크 |
쿼리 성능 | JOIN이 많을수록 성능 저하 | 관계 탐색 성능 일정 | 환자 진료 이력 추적 |
스키마 변경 | 어렵고 비용이 큼 | 유연하게 변경 가능 | 새로운 의료 프로토콜 추가 |
- Graph DB의 장점
항목 | Graph DB | RDB |
복잡한 관계 표현의 용이성 | 노드와 엣지를 사용하여 복잡한 관계를 직관적으로 표현 | 테이블과 조인으로 관계를 표현하며, 복잡도가 증가하면 관리 어려움 |
성능 향상 | 인접 노드를 따라 탐색하여 관계 중심의 쿼리에 높은 성능 제공 | 여러 조인이 필요한 관계 탐색 시 성능 저하 가능성 |
스키마의 유연성 | 스키마리스 또는 유연한 스키마로 데이터 구조 변경에 용이 | 고정된 스키마로 변경 시 복잡하고 시간 소요 |
자연스러운 데이터 모델링 | 현실 세계의 엔티티와 관계를 자연스럽게 모델링 가능 | 테이블 기반 모델링으로 복잡한 관계 표현에 한계 |
확장성 | 대용량 데이터와 복잡한 관계 처리에 효율적이며 분산 환경에서 유리 | 확장성이 제한적이며 대규모 데이터 처리 시 성능 저하 가능 |
강력한 쿼리 언어 | 관계 탐색과 패턴 매칭에 최적화된 Cypher 등 제공 | SQL은 집계와 필터링에 최적화되어 관계 탐색에는 비효율적 |
- 의료 데이터 사례
상황/시나리오 | 설명 | Graph DB의 이점 |
복잡한 환자 관계 관리 | 환자, 의사, 처방, 진단 등 다양한 엔티티의 복잡한 연관성 | 복잡한 관계를 효율적으로 관리하고 탐색 가능 |
신속한 관계 기반 질의 | 특정 약물 복용 환자 중 특정 유전적 표지를 가진 환자 탐색 | 관계를 따라 신속한 탐색으로 성능 향상 |
의료 지식 그래프 구축 | 질병, 증상, 약물, 유전자 간의 지식 네트워크 생성 | 지식 그래프를 효율적으로 저장하고 질의 가능 |
표준 데이터 모델과의 통합 | OMOP-CDM, HL7 FHIR 등의 복잡한 표준 모델 사용 | 복잡한 구조와 관계를 자연스럽게 표현하여 데이터 접근성 향상 |
환자 경로 분석 | 치료 과정, 방문 기록, 처방 내역 등을 통한 환자 경로 분석 | 그래프를 통해 병목 현상 발견 및 의료 서비스 효율성 증대 |
네트워크 기반 전염병 연구 | 전염병 확산 경로 모델링 및 분석 | 감염 경로 파악과 전염병 대응 전략 수립에 효율적 |
상호운용성 향상 | 다양한 의료 시스템과 데이터 소스의 통합 | 데이터의 상호운용성 향상으로 정보 공유 및 협업 촉진 |
실시간 데이터 분석 | 실시간 데이터 스트림 처리 및 즉각적인 관계 기반 분석 필요 | 빠른 의사 결정 지원으로 응급 의료 상황에 활용 가능 |
2. Cypher Agent
TEXT to SQL 과 유사한 아키텍처로
SQL이 아닌 Cuypher 문법의 쿼리를 작성해주는 agent
3. Code
from langchain_openai import ChatOpenAI
from langchain_community.graphs import Neo4jGraph
from langchain.chains import GraphCypherQAChain
from langchain.prompts import PromptTemplate
llm = ChatOpenAI(
openai_api_key=openai_api_key
)
graph = Neo4jGraph(
url="bolt://localhost:7687",
username="neo4j",
password="omoptograph",
database="omoptograph"
)
CYPHER_GENERATION_TEMPLATE = """
You are an expert Neo4j Developer specializing in OMOP-CDM data models and graph database queries.
Your role is to translate user questions into Cypher queries to extract meaningful insights from the OMOP-CDM-based Neo4j graph database.
Instructions:
1. Use only the provided node labels, relationship types, and properties from the schema.
2. Do not invent or assume any additional labels, relationships, or properties.
3. Ensure the query captures the full intent of the user's question while adhering strictly to the schema.
4. Prioritize efficient graph traversal using Neo4j best practices.
Schema: {schema}
Question: {question}
Output a Cypher query that accurately answers the user's question based on the provided schema.
"""
schema = """
Nodes:
- Person: {id: STRING, gender: STRING, birth_date: DATE}
- ConditionOccurrence: {condition_id: STRING, start_date: DATE, end_date: DATE}
- DrugExposure: {drug_id: STRING, start_date: DATE, end_date: DATE}
- ProcedureOccurrence: {procedure_id: STRING, date: DATE}
- VisitOccurrence: {visit_id: STRING, start_date: DATE, end_date: DATE}
- ObservationPeriod: {period_id: STRING, start_date: DATE, end_date: DATE}
Relationships:
- (:Person)-[:HAS_CONDITION_OCCURRENCE]->(:ConditionOccurrence)
- (:Person)-[:HAS_DRUG_EXPOSURE]->(:DrugExposure)
- (:Person)-[:HAS_PROCEDURE_OCCURRENCE]->(:ProcedureOccurrence)
- (:Person)-[:HAS_VISIT_OCCURRENCE]->(:VisitOccurrence)
- (:Person)-[:HAS_OBSERVATION_PERIOD]->(:ObservationPeriod)
- (:VisitOccurrence)-[:ASSOCIATED_DURING_VISIT]->(:ConditionOccurrence)
- (:VisitOccurrence)-[:ASSOCIATED_DURING_VISIT]->(:DrugExposure)
"""
cypher_generation_prompt = PromptTemplate(
template=CYPHER_GENERATION_TEMPLATE,
input_variables=["schema", "question"],
)
cypher_chain = GraphCypherQAChain.from_llm(
llm,
graph=graph,
cypher_prompt=cypher_generation_prompt,
verbose=True,
allow_dangerous_requests=True
)
- 결과 예시
https://github.com/eunchanj/omop_to_graph/tree/main