GIN (+ trigram)

김영준·2026년 4월 10일

멜로미

목록 보기
7/13

관련도 검색을 하려고 한다. 검색은 게시글 검색
우리 서비스에선 제목, 본문, 치료영역, 나이 이렇게 내용이 있음.

GIN

: 역인덱스 저장 + 역인덱스 탐색
<일반 인덱스>

IdxValue
1컴퓨터
2컴퓨터
3키보드
4마우스
5모니터

<역인덱스>

역인덱스Value
컴퓨터1,2
키보드3
마우스4
모니터5

trigram

: 글자를 세글자씩 쪼개는 것

Ex. 개발의 신이 될거예요
=> 개발의 / 발의" " / 의 신 / " "신이 / 신이" " / 이" "될 / " "될거 / 될거예 / 거예요

GIN + trigram

<일반 인덱스>

IdxValue
1번"컴퓨터마우스"
2번"컴퓨터키보드"
3번"키보드마우스"

<역인덱싱>

역인덱스Value
컴퓨터1,2
퓨터마1
터마우1
마우스1,3
터키보2
키보드2,3
보드마3

<검색어 입력시 동작 원리>

  1. trigram이 검색어 쪼갬
"컴퓨터마우스" => "컴퓨터"/"퓨터마"/"터마우"/"마우스"
  1. GIN이 역인덱스에서 각 trigram 탐색
"컴퓨터"  →  1, 2
"퓨터마"  →  1
"터마우"  →  1
"마우스"  →  1, 3
  1. 게시글별로 trigram 몇 개 겹쳤는지 카운터
1번 게시글: "컴퓨터" "퓨터마" "터마우" "마우스" → 4개 겹침
2번 게시글: "컴퓨터"                             → 1개 겹침
3번 게시글: "마우스"                             → 1개 겹침
  1. similarity() 점수 계산
1번: 4/4 겹침 → similarity 1.0  (완전 일치)
2번: 1/4 겹침 → similarity 0.25
3번: 1/4 겹침 → similarity 0.25

문제 상황

근데 게시판은 여러 데이터들이 모여있음. 예를들어 제목, 본문, 치료영역, 나이
등등 정보들이 모여있는데, 이걸 어떻게 trigram으로 나눠서 GIN을 적용시킬까?

해결책

  1. 각각 따로 GIN 적용해서 계산을 해, 가중치를 적용하자
  2. 역정규화로 모으자 !

1번 설명

각 테이블(데이터) 마다 점수를 계산함. 하지만 해당 IDX 자료구조를 데이터 개수만큼 방문해야함. 이게 트레이드 오프. 이걸 통해 얻을 수 있는건 가중치를 다르게 줘서 제목이 중요하다면 제목 가중치를 올리면 되는것. 커스텀이 가능함.

score = similarity(p.title,   :kw) * 3.0   -- 제목 일치가 가장 중요
      + similarity(p.content, :kw) * 1.0   -- 본문은 보조
      + therapyArea_score              * 1.5   -- Java 매핑값
      + ageGroup_score                 * 1.0   -- Java 매핑값

하지만 현재 서비스에서는 2번으로 진행하고, 후에 정확도가 필요하다고 판단되면 1번으로 리팩토링 할 예정

2번 설명

역정규화로 줄글로 모음 -> trigram -> GIN 진행

therapy_area = ART       → "미술치료"
age_group    = AGE_6_12  → "6세"

search_text = 제목 + " " + 본문 + " " + "미술치료" + " " + "6세"

여기서 트레이드 오프는 본문의 내용이 너무 길때가 문제가 된다.
만약 글자가 10000자라면 trigram은 9998개가 나옴. GIN 역인덱스에 9998개 엔트리 삽입해야함. 너무 큰 비용이라고 생각.
본문을 적을 때는, 앞에 중요 내용을 적을거라 생각하여 앞에서부터 100자만 포함하는 것이 합리적이라 생각.

제목 30자 + 본문 100자 + 치료영역 4자 + 나이 3자 => 약 150개의 trigram.

물론, 데이터 저장량이 훨씬 많음. 하지만 커뮤니티는 쓰기보다 읽기가 압도적으로 많을 것으로 예상됨. 따라서 검색의 FULL SCAN을 해결하고, 데이터를 좀 더 저장하는 편이 서비스차원에서 맞다고 생각함.

<요약>

커뮤니티 서비스 특성상 쓰기보다 읽기가 압도적으로 많음
→ 시간-공간 트레이드오프에서 공간을 희생하고 시간을 얻는 것이 유리
→ search_text 역정규화 + GIN trigram 채택

profile
개발의 신이 될거다

0개의 댓글