MongoDB 8.3: $scoreFusion GA와 self-managed 검색 완성 — 하이브리드 검색을 단일 데이터베이스에서 운영하는 방법
왜 이 릴리스를 지금 봐야 하나
2026년 5월 7일 공개된 MongoDB 8.3은 세 방향에서 동시에 진전한 릴리스다.
- $scoreFusion GA: 전문 검색과 벡터 검색의 점수를 수식으로 결합하는 집계 스테이지가 정식 기능이 됐다. Atlas에 이어 self-managed에서도 쓸 수 있다.
- Self-managed Search 경로 완성: 8.2에서 공개 프리뷰로 시작한 self-managed MongoDB Search와 Vector Search가 2026년 6월 30일 MongoDB Enterprise Advanced 기준으로 GA가 됐다.
- 쓰기/읽기 성능 향상: MongoDB 8.0 대비 쓰기 처리량 35%, 읽기 처리량 45% 향상. ACID 트랜잭션은 15% 빨라졌다.
이 세 가지는 서로 다른 문제에 답한다.
- 검색 품질: 텍스트 랭킹과 벡터 유사도를 나란히 갖되 순위 순서가 아니라 점수 수식으로 결합하면 더 세밀한 관련성 제어가 가능하다.
- 운영 단순성: 검색 인덱스를 위해 Elasticsearch 같은 별도 시스템을 동기화할 필요가 없다. 단일 MongoDB 클러스터에서 CRUD와 하이브리드 검색을 함께 운영한다.
- 기반 성능: 검색 기능과 무관하게 일반 워크로드의 처리량도 올라갔다.
업그레이드를 서두를 이유는 셋 중 어느 것이 현재 운영 병목인지로 판단하면 된다.
아키텍처 개요: mongod + mongot 두 프로세스 모델
1. mongot: 검색 인덱스를 트랜잭션 커밋 경로 밖에 두는 설계
MongoDB의 전문 검색과 벡터 검색을 self-managed에서 가능하게 한 핵심은 mongot다. mongot는 mongod와 별도로 실행되는 바이너리로, Apache Lucene을 기반으로 한 검색·벡터 인덱스 엔진이다.
왜 별도 프로세스인가
전문 검색 인덱스 구축은 무거운 연산이다. 텍스트를 분석하고 역인덱스를 만들고, 벡터 인덱스(HNSW 그래프)를 구성하는 작업을 트랜잭션 커밋 경로에 넣으면 쓰기 지연이 크게 올라간다.
mongot는 이 연산을 트랜잭션 커밋 이후로 비동기 분리한다. 동작 방식은 이렇다.
- 애플리케이션이
mongod에 도큐먼트를 쓴다. 트랜잭션은 WiredTiger에서 커밋된다. mongod의 oplog가 변경을 기록한다.- mongot가 Change Streams를 통해 이 변경을 비동기로 수신한다.
- mongot가 자체 Lucene 인덱스와 벡터 인덱스를 업데이트한다.
쓰기 지연은 mongot 인덱스 동기화에 영향받지 않는다. 대신 $search와 $vectorSearch 쿼리는 약간의 인덱스 지연을 가진다. 이 지연은 클러스터 부하에 따라 다르지만 보통 수백 밀리초에서 수 초 이내다.
배포 방식
mongot는 두 가지 토폴로지로 배포할 수 있다.
사이드카 모드: mongod와 동일한 노드에서 실행한다. 자원을 공유하며 간단하게 시작할 수 있다. 중소 규모 워크로드에 적합하다.
독립 서비스 모드: mongot 프로세스를 별도 서버군에 배포하고 로드밸런서 뒤에 둔다. mongod와 mongot 자원을 분리해 독립적으로 스케일할 수 있다. 검색 쿼리가 많거나 인덱스 크기가 큰 경우에 선택한다.
샤드 클러스터에서는 각 샤드마다 mongot가 실행된다. 검색 쿼리는 각 샤드의 로컬 인덱스를 검색한 뒤 결과를 mongos에서 합친다.
source-available 공개
MongoDB는 mongot 엔진을 소스 공개(source-available)로 전환했다. 라이선스는 Atlas와 동일한 제약이 있지만, 코드 수준에서 인덱싱 동작을 이해하거나 기여할 수 있는 경로가 생겼다.
2. $scoreFusion: 순위가 아닌 점수로 결합한다
$rankFusion의 한계
8.2에서 도입된 $rankFusion은 Reciprocal Rank Fusion(RRF) 알고리즘을 사용한다. 각 파이프라인에서 문서의 순위(position) 를 기반으로 점수를 계산한다.
RRF score = 1 / (k + rank) (k=60이 기본값)순위 기반 결합은 단순하다. 전문 검색 결과 1위, 벡터 검색 결과 3위인 문서는 순위만 갖고 결합된다. 그런데 이 방식은 점수 값 자체를 버린다. 전문 검색에서 0.98 점을 받은 문서와 0.51 점을 받은 문서가 순위만 같으면 같은 가중치를 받는다.
$scoreFusion의 동작
8.3에서 GA가 된 $scoreFusion은 점수 값을 정규화해 수식으로 결합한다.
{
$scoreFusion: {
input: {
pipelines: {
text: [
{ $search: { index: "text_idx", text: { query: "데이터베이스", path: "title" } } }
],
vector: [
{ $vectorSearch: { index: "vec_idx", queryVector: [...], numCandidates: 100, limit: 20 } }
]
}
},
combination: {
weights: {
text: 0.4,
vector: 0.6
}
}
}
}각 파이프라인은 독립적으로 실행되고, 결과를 문서 단위로 dedup한 뒤, 가중 합산한 점수로 최종 순위를 결정한다.
$rankFusion과 $scoreFusion 선택 기준
| 상황 | 권장 방식 |
|---|---|
| 빠르게 하이브리드 검색을 시작할 때 | $rankFusion (단순, 조율 불필요) |
| 텍스트 관련성과 벡터 유사도의 상대적 중요도를 세밀하게 제어할 때 | $scoreFusion |
| 점수가 파이프라인마다 스케일이 크게 다를 때 | $scoreFusion (정규화 적용) |
| 검색 품질 A/B 테스트가 필요할 때 | $scoreFusion (가중치 변경으로 실험) |
$scoreFusion은 8.2 이상에서만 쓸 수 있다.
3. self-managed Search: 운영자가 알아야 할 인덱스 동기화 경계
self-managed 배포에서 Search를 쓰기 시작하기 전에 이해해야 할 운영 특성이 있다.
인덱스 지연(Index Lag)
Change Streams 기반 비동기 복제이므로 도큐먼트가 mongod에 커밋된 후 mongot 인덱스에 반영되기까지 시간이 걸린다. 읽기 지연이 매우 민감한 워크로드(예: 방금 저장한 데이터를 바로 검색해야 하는 경우)는 인덱스 지연을 고려해야 한다.
레플리카셋과 샤드 클러스터
- 레플리카셋에서는 Primary에 mongot가 붙는다. Primary failover가 발생하면 mongot도 새 Primary에 연결될 때까지 잠시 동기화가 멈춘다.
- 샤드 클러스터에서는 각 샤드에 mongot가 있다. 새 샤드를 추가하면 mongot 인스턴스도 프로비저닝해야 한다.
리소스 계획
mongot는 Lucene 기반이므로 JVM 메모리를 사용한다. 전문 검색 인덱스와 벡터 인덱스 크기, 동시 쿼리 수에 따라 메모리가 달라진다. 사이드카 모드에서는 mongod와 mongot의 메모리 합산이 서버 총 RAM을 넘지 않아야 한다.
백업
mongot 인덱스는 Change Streams를 통해 재구축할 수 있으므로 별도로 백업하지 않아도 된다. 단, 인덱스 재구축에는 시간이 걸린다. 도큐먼트 수가 많으면 재구축 완료 전까지 검색 결과가 부정확하거나 없을 수 있다.
4. 성능 향상: 35% 쓰기, 45% 읽기
이번 릴리스의 성능 수치는 MongoDB 8.0 대비 측정값이다. 주요 개선이 두 가지다.
Generic Query Plans
8.3은 Generic Query Plans(범용 쿼리 플랜)를 도입한다. 기존 플랜 캐싱은 파라미터 값에 따라 플랜이 달라질 수 있어서, 같은 쿼리 형태라도 다른 플랜이 선택되곤 했다.
Generic Query Plans는 파라미터에 독립적인 일반 플랜을 미리 컴파일해 재사용한다. OLTP 스타일의 짧고 반복적인 쿼리가 많은 환경에서 CPU 오버헤드가 줄어든다.
Buffered Writes
Buffered Writes는 쓰기 작업을 묶어서 처리한다. 짧은 시간 안에 들어오는 여러 건의 쓰기를 배치로 합쳐 스토리지 레이어에 내려보낸다. 개별 트랜잭션의 커밋 횟수를 줄여 처리량을 높인다.
이 최적화가 ACID 트랜잭션 언어 보장을 깨지 않는다는 점이 중요하다. 트랜잭션 격리와 원자성은 그대로다. Buffered Writes는 물리 I/O 레이어의 최적화다.
5. arrayIndexAs: 집계 표현식의 작은 개선, 큰 편의성
8.3에서 추가된 arrayIndexAs 필드는 $map, $filter, $reduce 집계 표현식에서 배열 원소의 인덱스를 변수로 직접 참조할 수 있게 한다.
이전에는 배열을 처리하면서 순서 번호가 필요할 때 별도 변환 단계가 필요했다. 8.3에서는 이렇게 쓸 수 있다.
{
$project: {
indexed: {
$map: {
input: "$items",
as: "item",
arrayIndexAs: "idx",
in: {
position: "$idx",
value: "$item"
}
}
}
}
}작은 기능이지만, 배열 위치 정보를 쿼리에서 직접 쓰는 패턴(예: 배열의 N번째 원소에 가중치 부여, 순서 기반 필터)에서 집계 파이프라인이 단순해진다.
6. Self-managed vs Atlas: 무엇이 여전히 다른가
MongoDB 8.3은 self-managed와 Atlas 간의 기능 간격을 줄였지만, 여전히 차이가 있다.
| 기능 | Atlas | Self-managed 8.3 |
|---|---|---|
| 전문 검색 + 벡터 검색 | GA | GA (Enterprise Advanced 기준) |
| $scoreFusion | GA | GA (8.2+) |
| $rankFusion | GA | GA (8.2+) |
| 자동 인덱스 관리 | 예 (Atlas Search 자동) | 수동 구성 필요 |
| mongot 운영 | Atlas 관리 | 직접 운영 |
| 다중 클라우드 글로벌 클러스터 | 예 | 직접 구성 필요 |
| Queryable Encryption | GA | GA (8.0 이상) |
Self-managed를 선택하는 주된 이유는 데이터 거주지(data residency) 규제, 기존 온프레미스 인프라 활용, 클라우드 비용 최적화다. 이 세 가지 요건 중 하나라도 해당하면 self-managed 경로가 현실적이다.
운영자 도입 체크리스트
- [ ] mongot 배포 토폴로지 결정: 사이드카(작은 클러스터)와 독립 서비스(큰 클러스터, 자원 분리) 중 어느 것이 맞는지 먼저 정한다.
- [ ] 메모리 계획: 사이드카 모드에서는 mongod + mongot 합산 메모리가 서버 RAM 내에 있어야 한다. mongot JVM 힙 설정을 인덱스 크기에 맞게 조정한다.
- [ ] 인덱스 지연 허용 여부 확인: 방금 쓴 데이터를 즉시 검색해야 하는 요건이 있으면 인덱스 지연을 설계에 반영한다.
- [ ] $scoreFusion 가중치 실험: 텍스트와 벡터 가중치를 어떻게 설정하느냐에 따라 검색 품질이 크게 달라진다. 오프라인에서 샘플 쿼리로 실험한 뒤 프로덕션에 적용한다.
- [ ] $rankFusion과 비교 테스트: 단순한 워크로드에서는 $rankFusion이 충분하다. 두 방식을 같은 쿼리 세트로 비교해 실제로 $scoreFusion이 품질을 높이는지 확인한다.
- [ ] 샤드 클러스터에서 mongot 인스턴스 배포 자동화: 샤드가 추가될 때 mongot도 함께 배포되도록 IaC(Terraform, Ansible)나 Kubernetes Operator에 포함한다.
- [ ] 백업 시나리오에서 인덱스 재구축 시간 측정: 복구 후 인덱스 재구축 완료까지 검색이 정확하지 않을 수 있다는 점을 runbook에 명시한다.
- [ ] Generic Query Plans 효과 모니터링:
explain()출력에서GENERIC_PLAN사용 여부를 확인한다. 일부 복잡한 쿼리에서는 Generic Plan이 최적이 아닐 수 있다. - [ ] MongoDB 8.0 → 8.3 직접 업그레이드 경로 확인: 중간 버전을 건너뛰는 업그레이드 지원 여부를 공식 문서에서 확인한다.
어디까지를 기대하고, 어디부터는 아직 이른가
MongoDB 8.3은 self-managed에서 하이브리드 검색(전문 + 벡터)을 현실적인 운영 옵션으로 만들었다.
그러나 Atlas 대비 운영 부담이 늘어난다는 점을 무시하면 안 된다. mongot 프로세스 모니터링, 인덱스 지연 관리, JVM 힙 튜닝이 새로운 운영 책임으로 들어온다. "Elasticsearch 대신 MongoDB Search"라는 구성이 가능해졌지만, Elasticsearch의 성숙한 운영 도구(Kibana, APM 연동, ILM 정책)를 대체하는 수준은 아직 아니다.
$scoreFusion은 $rankFusion보다 유연하지만 조율 비용이 있다. 가중치를 잘못 잡으면 검색 품질이 오히려 나빠진다. 팀에 검색 품질을 평가할 ground truth 데이터셋과 평가 파이프라인이 없다면, $rankFusion부터 시작하는 편이 낫다.
Open question
- self-managed Enterprise Advanced와 Community Edition의 Search 기능 범위 차이(예: RBAC 통합, 감사 로그 연동)가 정확히 어디까지인지는 공식 문서 확인이 필요하다.
arrayIndexAs의 $filter, $reduce 지원이 8.3 출시 시점에 모두 GA인지, 일부는 preview인지 추가 확인이 필요하다.
References
- https://www.mongodb.com/products/updates/mongodb-8-3/
- https://www.mongodb.com/company/blog/product-release-announcements/ai-changing-what-customers-need-from-database-mongodb-8-3-built-for-it
- https://gilbane.com/2026/05/mongodb-releases-mongodb-8-3/
- https://www.mongodb.com/docs/manual/release-notes/8.3/
- https://www.mongodb.com/docs/manual/reference/operator/aggregation/scorefusion/
- https://www.mongodb.com/company/blog/product-release-announcements/supercharge-self-managed-apps-search-vector-search-capabilities
- https://www.mongodb.com/company/blog/product-release-announcements/now-source-available-the-engine-powering-mongodb-search
- https://sdtimes.com/data/mongodb-brings-search-and-vector-search-to-self-managed-versions-of-database/
- https://www.mongodb.com/docs/manual/release-notes/8.2/