DOCS/journey/research/rag/260320_PostgreSQL_그래프확장_설계_리서치.md

5.3 KiB

tags, type, status, research_target
tags type status research_target
research
rag
robeing
postgres
graph
relations
research open PostgreSQL 기반 문서 관계 탐색과 그래프 확장 방식 정리

PostgreSQL 그래프확장 설계 리서치

상태

  • updated (260320: 재귀 CTE → Apache AGE로 방향 변경)

작성일: 2026-03-20 목적: PostgreSQL 안에서 문서 연결성과 탐색성을 확보하는 방법을 정리한다.


1. 결론

  • 재귀 CTE로 충분Apache AGE(PostgreSQL 그래프 확장)를 도입한다.
  • AGE는 PostgreSQL 위에서 Cypher 쿼리를 지원하여, 복잡한 문서 관계 탐색을 직관적으로 처리한다.
  • 기존 PGVector + JSONB와 같은 DB 커넥션 안에서 벡터 검색 → 그래프 탐색 하이브리드 쿼리가 가능하다.

1.1 왜 Apache AGE인가

  • Cypher 지원: MATCH (d:Doc)-[:RELATED]->(r:Doc) 식의 직관적 관계 탐색. 재귀 CTE 대비 쿼리 복잡도 대폭 감소.
  • PGVector 동거: 벡터 검색으로 후보군 → AGE로 맥락 확장이 하나의 DB에서 끝남.
  • 운영 단순화: 별도 그래프 DB(Neo4j 등) 없이 PostgreSQL 하나로 통합.

1.2 설치 주의사항

  • PostgreSQL 버전과 맞춰 컴파일 필요 — Docker 기반 설치 권장.
  • 에이전트가 Cypher를 구사하려면 프롬프트 DB에 Few-shot 예제 필요.

2. 연결 원천

  • front matter의 related
  • 공통 tags
  • 공통 keywords
  • 같은 폴더/프로젝트/작성자
  • 벡터 유사도 상 가까운 문서

3. 권장 테이블

create table if not exists document_relations (
    id bigserial primary key,
    from_document_id bigint not null references document_files(id) on delete cascade,
    to_document_id bigint not null references document_files(id) on delete cascade,
    relation_type text not null,
    weight numeric(6,3),
    metadata_jsonb jsonb not null default '{}'::jsonb,
    created_at timestamptz not null default now(),
    unique (from_document_id, to_document_id, relation_type)
);

create index if not exists idx_document_relations_from
    on document_relations (from_document_id);

create index if not exists idx_document_relations_to
    on document_relations (to_document_id);

create index if not exists idx_document_relations_metadata
    on document_relations using gin (metadata_jsonb);

4. relation_type 예시

  • explicit_related
  • same_folder
  • same_project
  • shared_tag
  • shared_keyword
  • semantic_neighbor
  • derived_from

5. 내가 추천하는 연결 생성 방식

5.1 명시 연결 우선

  • front matter의 related는 사람이 검증한 연결이므로 신뢰도가 높다.

5.2 규칙 기반 연결 다음

  • 같은 폴더, 같은 프로젝트, 같은 태그 등은 자동 생성하기 쉽다.

5.3 벡터 기반 연결은 후순위

  • 유사도만으로 연결하면 오탐이 많을 수 있다.
  • semantic_neighbor는 보조 연결로만 두는 것이 맞다.

6. 재귀 탐색 예시

with recursive related_docs as (
    select
        df.id,
        df.title,
        0 as depth
    from document_files df
    where df.id = $1

    union all

    select
        df2.id,
        df2.title,
        rd.depth + 1
    from related_docs rd
    join document_relations dr
      on dr.from_document_id = rd.id
    join document_files df2
      on df2.id = dr.to_document_id
    where rd.depth < 3
)
select distinct id, title, min(depth) as min_depth
from related_docs
group by id, title
order by min_depth, id;

7. AGE 그래프 스키마 (운영 반영 전제)

노드

  • Document: 문서 (title, source_path, file_type, tags)
  • Folder: 폴더/프로젝트 단위
  • Tag: 태그/키워드
  • User: 작성자/소유자

엣지

  • RELATED: 명시적 연결 (front matter related)
  • IN_FOLDER: 문서 → 폴더
  • TAGGED: 문서 → 태그
  • AUTHORED: 작성자 → 문서
  • SEMANTIC_NEIGHBOR: 벡터 유사도 기반 보조 연결

Cypher 쿼리 예시

-- 특정 문서의 2단계 관련 문서 탐색
MATCH (d:Document {title: '사업계획서'})-[:RELATED*1..2]-(r:Document)
RETURN r.title, r.source_path

-- 같은 폴더 + 같은 태그 문서
MATCH (d:Document)-[:IN_FOLDER]->(f:Folder)<-[:IN_FOLDER]-(r:Document)
WHERE d.title = '감사계약서'
RETURN r.title

8. 현재 추천

  • 51123 서버 PostgreSQL에 Apache AGE Docker 기반 설치.
  • document_relations 테이블 대신 AGE 그래프로 관계 관리.
  • PGVector(의미검색) + AGE(관계탐색)를 하나의 DB에서 하이브리드 운용.

8-1. 현재 구현 반영 (2026-03-22)

  • Apache AGE는 더 이상 예정이 아니라 운영 중이다.
  • 검색 경로에서도 graph_score가 합산되고, companyx_docs, document_graph 그래프가 실제로 존재한다.
  • 따라서 이 문서의 남은 역할은 왜 AGE를 쓰는가보다 운영 그래프를 어떤 규칙으로 유지할 것인가에 가깝다.

Unresolved

  • 그래프 노드/엣지 생성 규칙의 최종 SSOT가 아직 약하다.
  • 삭제·이동·재색인 시 그래프를 언제 갱신하고 언제 재구성할지 운영 기준이 부족하다.

10. 관련 문서