Java에서 MongoDB 문서를 읽기 위해 어떤 Document 클래스를 사용하는 것이 가장 좋나요?
Source: Dev.to
TL;DR
답은 제목에 있습니다 – Document를 사용하세요.
개요
BSON은 MongoDB가 효율적인 저장 및 네트워크 전송을 위해 사용하는 바이너리 직렬화 포맷(프로토버프와 유사)입니다.
전체 바이트 시퀀스를 스캔하고 다시 쓰는 대신, 메모리 상 객체를 사용하여 편리한 메서드로 필드를 읽고 쓸 수 있습니다.
서버 측에서는 MongoDB가 가변 BSON 객체를 사용하고, 클라이언트 측 Java 드라이버는 Bson 인터페이스를 구현한 여러 클래스를 제공합니다.
아래는 MongoDB Java 드라이버에서 제공하는 다섯 가지 문서 클래스와 그 특성, 그리고 언제 각각을 선택해야 하는지에 대한 간결한 가이드입니다.
1. Document (대부분의 애플리케이션에 권장)
- 타입:
Map(삽입 순서를 보존하기 위해LinkedHashMap기반) - 주요 특성
- 느슨하게 타입 지정: 값은 일반 Java 객체(
String,Integer,Date등) - 유연함: 동적으로 구조가 변하는 문서를 쉽게 다룰 수 있음
- Map API: 모든 표준
Map연산을 사용할 수 있음
- 느슨하게 타입 지정: 값은 일반 Java 객체(
- 사용 시점
- 간결하고 유연한 표현이 필요하고 “그대로 동작”하길 원할 때
- 엄격한 BSON 타입 안전성이 필요하지 않을 때
2. BsonDocument
- 타입:
Map(마찬가지로LinkedHashMap기반) - 주요 특성
- 타입 안전: 모든 값은 BSON 라이브러리 타입(
BsonString,BsonInt32,BsonDocument등)이어야 함 - 엄격한 API: 컴파일 타임 안전성을 제공하지만 코드가 다소 길어짐
- Map API:
Document와 동일하지만BsonValue를 사용함
- 타입 안전: 모든 값은 BSON 라이브러리 타입(
- 사용 시점
- BSON 타입을 명시적으로 제어해야 할 때(예: 정확한 타입 처리,
BsonDocument를 요구하는 API와 연동)
- BSON 타입을 명시적으로 제어해야 할 때(예: 정확한 타입 처리,
3. RawBsonDocument
- 타입: 원시 바이트 배열(BSON 문서)을 감싸는 불변 래퍼
- 주요 특성
- 불변: 변형 연산은
UnsupportedOperationException을 발생시킴 - 지연 파싱: 데이터는 필요할 때만 파싱 – 전달(pass‑through) 시나리오에 최적
- 메모리 효율: 중간 Java 객체가 생성되지 않음
- 변환:
decode(codec)을 사용해 필요 시 다른 문서 타입으로 변환 가능
- 불변: 변형 연산은
- 사용 시점
- 전체 문서 작업에서 최대 성능·메모리 효율을 원할 때
- 다음과 같은 경우:
- 문서를 읽고 그대로 전달(예: 변경 스트림, 클라이언트 측 암호화)
- 필드별로 검사할 필요가 없는 매우 큰 문서를 다룰 때
- 파싱 오버헤드가 중요한 고처리량 파이프라인
4. JsonObject
- 타입: JSON 문자열(
String)을 감싸는 단순 래퍼 - 주요 특성
Map을 구현하지 않으며, 단순히 문자열을 보관하고 선택적으로 검증함- 파싱이 수행되지 않아 원시 JSON이 그대로 유지됨
- MongoDB Extended JSON 형식을 지원함
- 사용 시점
- 애플리케이션이 주로 JSON을 다루는 경우(예: REST API, 로깅, JSON 형태로 문서 저장)
Map으로 변환하는 비용을 피하고 싶을 때
5. BasicDBObject (레거시)
- 타입:
BasicBSONObject를 상속하고DBObject를 구현(Map은 구현하지 않음) - 주요 특성
- 버전 3.0 이전 드라이버와의 호환성을 위해 존재
- 최신
Map편의 메서드가 부족함 - 바이너리 호환성 문제를 일으킬 수 있음
- 사용 시점
- 이미
BasicDBObject를 사용하고 있는 기존 코드를 마이그레이션할 때 - 새로운 개발에서는 사용 금지 – 드라이버 문서에서 사용을 피하도록 권고함.
- 이미
Source: …
클래스 간 변환
다섯 클래스 모두 Bson 인터페이스를 구현하므로 드라이버 작업에서 서로 교체하여 사용할 수 있습니다(성능 차이는 있을 수 있음).
| From → To | Example |
|---|---|
| JSON → BsonDocument | BsonDocument.parse(jsonString) |
| Raw bytes → other type | RawBsonDocument.decode(codec) |
| Document → BsonDocument | Use a CodecRegistry/DocumentCodec (or document.toBsonDocument(... )) |
| BsonDocument → Document | documentCodec.decode(bsonDocument.asBsonReader()) |
| JsonObject → JSON string | jsonObject.getJson() |
| RawBsonDocument ↔ Document | Encode/decode via a Codec (e.g., DocumentCodec) |
빠른 결정 가이드
| 요구 사항 | 선호 클래스 |
|---|---|
| 일반 목적, 유연하고 사용하기 쉬움 | Document |
| 엄격한 BSON‑type 안전성 필요 | BsonDocument |
| 성능을 위한 불변 원시‑바이트 표현 원함 | RawBsonDocument |
| JSON 문자열만 사용 | JsonObject |
| 레거시 코드 유지 (pre‑3.0 driver) | BasicDBObject |
요약
- **
Document**는 대부분의 애플리케이션에 기본 선택이며, 유연성, 단순성, 그리고 기능성을 균형 있게 제공합니다. - **
BsonDocument**는 컴파일 시점 타입 안전성이 필요할 때 선택합니다. - **
RawBsonDocument**는 고성능·메모리 효율적인 패스스루 시나리오에 적합합니다. - **
JsonObject**는 워크플로우가 순수 JSON을 중심으로 할 때 사용합니다. - **
BasicDBObject**는 레거시 마이그레이션에만 사용을 제한합니다.
모든 클래스는 드라이버의 코덱을 통해 서로 변환할 수 있으므로, 가장 편리한 타입으로 시작한 뒤 성능이나 타입 안전성 요구가 바뀔 경우 나중에 전환할 수 있습니다.
Overview
이 텍스트는 **RawBsonDocument**와 **Document**가 파싱 전략, 메모리 사용량, 가변성 측면에서 어떻게 다른지 설명합니다. 또한 Oracle과 PostgreSQL에서 유사한 개념이 제공되는지 비교하고, 현대 애플리케이션에 대한 MongoDB의 장점을 강조합니다.
RawBsonDocument vs. Document
RawBsonDocument
- Parsing strategy – BSON 문서를 순차적으로 읽으며, 요청된 키를 찾을 때까지 각 필드의 타입과 이름을 검사합니다.
- Field handling – 일치하는 필드만
RawBsonValueHelper.decode로 디코딩하고, 다른 필드는 파싱하지 않고 건너뜁니다. - Nested structures – 중첩된 문서와 배열의 경우, 크기만 읽고 해당 바이트 범위를 새로운
RawBsonDocument또는RawBsonArray인스턴스로 래핑하여 내용을 원시 바이트 그대로 유지합니다. - Performance – 단일 필드 조회가 빠르고 메모리 효율적이며 문서를 불변으로 유지합니다.
- Use case – 대용량 문서에서 몇 개의 필드만 필요하거나, 문서를 거의 검사 없이 그대로 전달할 때 이상적입니다.
Document
- Parsing strategy – 완전히 역직렬화된
LinkedHashMap을 사용합니다. - Eager parsing –
Document가 생성될 때 모든 필드가 Java 객체로 파싱됩니다. - Field access –
containsKey등 조회는 간단한HashMap연산으로 수행됩니다. - Mutability – 문서가 완전히 가변이며
put,remove,clear등을 지원합니다. - Memory usage – 모든 필드가 Java 객체로 실체화되므로 메모리 사용량이 더 많습니다.
- Use case – 중소 규모 문서이거나 다수의 필드에 접근해야 하거나, 문서를 자주 수정해야 하는 경우에 적합합니다.
Note:
Document는 파싱이나 필드 접근에RawBsonDocument를 사용하지 않습니다. 이는 비효율적이기 때문이며, 두 클래스는 서로 다른 목적을 위해 설계되었습니다.
BSON‑like Support in Other Databases
Oracle
- No BSON – Oracle은 BSON 대신 OSON(Oracle의 바이너리 JSON 포맷)으로 JSON을 저장합니다.
- Closest equivalent –
OracleJsonObject(여러OracleJsonValue타입 중 하나)를javax.json.JsonObject로 노출하거나 도메인 객체에 매핑할 수 있습니다. - Efficiency – OSON API는 문서를 완전히 파싱하지 않고도 기본 바이트에 직접 작업합니다. 필드 이름의 로컬 사전, 해시 코드 정렬 배열, 압축된 필드‑ID/값 오프셋 배열을 유지하여 드라이버가 이진 검색을 통해 필드를 제자리에서 찾을 수 있게 합니다.
- JSON text – JSON 텍스트가 필요하면
ResultSet.getString()을 호출하면 OSON 이미지를 클라이언트 측에서 JSON으로 변환합니다.
PostgreSQL
- No native Java JSON object API –
json및jsonb컬럼은 JDBC 드라이버를 통해 텍스트 형태로 반환됩니다. - Parsing responsibility – 애플리케이션이 별도의 JSON 라이브러리를 사용해 반환된 문자열을 파싱해야 합니다.
- Binary storage –
jsonb는 서버에서 바이너리 포맷으로 데이터를 저장하지만, 이 효율성은 전송 과정에서는 적용되지 않으며 클라이언트는 여전히 텍스트를 받아 필드에 접근하기 전에 전체 파싱을 수행합니다.
MongoDB’s Advantage
- Domain‑object centric – MongoDB는 중간 ORM 레이어 없이 도메인 객체와 직접 작업할 수 있게 해줍니다.
Documentclass – 문서 객체 모델(DOM) 역할을 하며, 유연한 맵 스타일 접근과 자연스러운 Java 인터페이스를 제공합니다.- Transparent conversion – 드라이버가 네트워크에서 받은 BSON을 자동으로 사용 가능한 Java 객체로 변환하므로, 애플리케이션에서 즉시 활용할 수 있습니다.