AI 에이전트의 경우: 문서 인덱스는 https://www.mongodb.com/ko-kr/docs/llms.txt에서 사용할 수 있으며, 모든 페이지의 마크다운 버전은 어떤 URL 경로에 .md를 추가하여 사용할 수 있습니다.
Docs Menu

유형 코덱으로 데이터 인코딩

이 가이드에서는 Scala 드라이버에서 BSON 데이터에 대한 Scala 객체의 인코딩 및 디코딩을 처리하는 코덱 및 지원 클래스에 대해 학습할 수 있습니다. Codec 추상을 사용하면 모든 Scala 유형을 해당 BSON 유형에 매핑할 수 있습니다. 이를 사용하여 Document 또는 BsonDocument 같은 중간 맵 기반 객체에 의지하는 대신 도메인 객체를 BSON에 직접 매핑하거나 BSON에서 직접 매핑할 수 있습니다.

Codec 인터페이스에는 Scala 객체를 BSON 데이터로 인코딩 및 디코딩하기 위한 추상 메서드가 포함되어 있습니다. 이 메서드를 구현하여 BSON과 Codec 구현의 Scala 유형 간의 변환 로직을 정의합니다.

인터페이스를 구현 하려면 Codec encode()인터페이스의, decode()getEncoderClass() 메서드를 정의합니다. 이러한 메서드를 구현하는 코드 예시 보려면 기본 사용자 지정 코덱 예제 섹션을 참조하세요.

encode() 메서드는 Scala 유형의 인스턴스를 BSON으로 인코딩하여 드라이버가 MongoDB에 저장할 수 있도록 합니다. 이 메서드에는 다음 매개 변수가 필요합니다.

Parameter Type
설명

writer

BSON 문서 작성을 위한 메서드를 노출하는 인터페이스인 BsonWriter를 구현하는 클래스의 인스턴스입니다. 이 인스턴스를 사용하여 BSON 값 유형에 대한 적절한 쓰기 (write) 메서드를 사용하여 BSON 값을 작성합니다.

value

메서드가 인코딩하는 데이터입니다. value 유형은 Codec 구현에 할당한 유형 매개변수와 일치해야 합니다.

encoderContext

현재 값을 MongoDB 컬렉션에 저장할지 여부를 포함하여 메서드가 BSON으로 인코딩하는 Scala 객체에 대한 메타데이터가 포함되어 있습니다.

encode() 메서드는 값을 반환하지 않습니다.

decode() 메서드는 BSON 데이터를 사용하여 Scala 유형의 인스턴스를 디코딩합니다. 이 메서드에는 다음 매개 변수가 필요합니다.

Parameter Type
설명

bsonReader

BSON 문서를 읽기 위한 메서드를 노출하는 인터페이스인 BsonReader를 구현하는 클래스의 인스턴스입니다.

decoderContext

메서드가 Scala 객체로 디코딩하는 BSON 데이터에 대한 메타데이터입니다.

getEncoderClass() 메서드는 Codec에 정의된 Scala 유형의 인스턴스를 반환합니다. 이 메서드는 Java Virtual Machine(JVM)이 런타임에 지우는 유형 정보를 제공합니다.

다음 코드 샘플에서는 PowerStatus 밀봉 트레이트와 PowerStatusCodec 클래스를 사용하여 사용자 지정 Codec를 구현하는 방법을 보여줍니다.

PowerStatus 밀봉한 트레이트는 사례 객체 OnOff를 사용하여 전기 스위치의 상태를 나타냅니다.

sealed trait PowerStatus
object PowerStatus {
case object On extends PowerStatus
case object Off extends PowerStatus
}

PowerStatusCodec 클래스는 Codec 인터페이스를 구현하여 PowerStatus 값을 해당 BSON 불리언 값으로 인코딩합니다. encode() 메서드는 PowerStatus 값을 BSON 불리언 값으로 인코딩하고 decode() 메서드는 BSON 불리언 값을 PowerStatus 값으로 데코딩합니다.

class PowerStatusCodec extends Codec[PowerStatus] {
override def encode(writer: BsonWriter, value: PowerStatus,
encoderContext: EncoderContext): Unit = {
if (value != null) {
writer.writeBoolean(value == PowerStatus.On)
}
}
override def decode(reader: BsonReader,
decoderContext: DecoderContext): PowerStatus = {
if (reader.readBoolean()) PowerStatus.On else PowerStatus.Off
}
override def getEncoderClass: Class[PowerStatus] = classOf[PowerStatus]
}

PowerStatusCodec CodecRegistry Codec 클래스를 사용하려면 CodecRegistry 를 해당 스칼라 유형에 Codec 매핑하는 인터페이스에 Codec 클래스의 CodecRegistry 인스턴스 를 추가해야 합니다. 운전자 에 해당 유형에 대한 가 포함된 경우에만 유형을 인코딩 및 디코딩할 수 있습니다. 인터페이스에 사용자 지정 를 포함하는 방법을 학습 이 페이지의 CodecRegistry 섹션을 참조하세요.

이 섹션의 클래스 및 인터페이스에 대한 자세한 내용은 다음 API 설명서를 참조하세요.

CodecRegistryCodec 인스턴스의 변경 불가능한 컬렉션입니다. CodecRegistry 인스턴스를 구축하려면 다음 CodecRegistries 클래스 정적 팩토리 메서드 중 하나를 사용합니다. 각 메서드는 다른 Codec 인스턴스 소스에서 레지스트리를 빌드합니다.

메서드
설명

fromCodecs()

메서드에 전달하는 Codec 인스턴스에서 레지스트리를 빌드합니다.

fromProviders()

메서드에 전달하는 CodecProvider 인스턴스가 제공하는 Codec 인스턴스에서 레지스트리를 빌드합니다.

fromRegistries()

메서드에 전달하는 다른 CodecRegistry 인스턴스를 결합하여 레지스트리를 빌드합니다.

다음 예시에서는 두 개의 Codec 구현을 사용합니다.

  • IntegerCodec: Java Integer 값을 BSON 32비트 정수 값으로 인코딩하는 BSON 패키지의 Codec 입니다.

  • PowerStatusCodec: 값을 BSON 부울로디코딩하는 샘플 입니다.Codec PowerStatus

다음 예시는 fromCodecs() 메서드를 사용하여 이 구현을 레지스트리에 할당하여 CodecRegistry 인스턴스를 구성하는 방법을 보여줍니다.

val codecRegistry = CodecRegistries.fromCodecs(
new IntegerCodec(), new PowerStatusCodec()
)

다음 예시에서는 이전 예시의 Codec 인스턴스를 CodecRegistry 컬렉션에서 조회합니다.

val powerStatusCodec: Codec[PowerStatus] =
codecRegistry.get(classOf[PowerStatus])
val integerCodec: Codec[Integer] =
codecRegistry.get(classOf[Integer])

참고

등록되지 않은 클래스의 Codec 인스턴스에서 get() 메서드를 호출하면 드라이버가 CodecConfigurationException를 시작합니다.

기본값 코덱 레지스트리는 일반적으로 사용되는 스칼라 와 MongoDB 유형을 서로 인코딩하는 클래스 설정하다 입니다. 사용자 지정 코덱 레지스트리를 지정하지 않는 한 운전자 자동으로 기본값 코덱 레지스트리를 사용합니다. 인터페이스에 대해 CodecProvider CodecProvider 자세히 학습 CodecProvider 섹션을 참조하세요.

하나 이상의 Codec 클래스 동작을 재정의해야 하지만 다른 클래스의 기본 코덱 레지스트리의 동작은 그대로 유지하려면 모든 레지스트리를 우선 순서대로 지정할 수 있습니다. 예를 들어 사용자 지정 유형에 대한 Codec의 기본 제공자 동작을 MyEnumCodec로 재정의하려면 기본 코덱 레지스트리 이전에 레지스트리 목록에 추가해야 합니다. 다음 예시에서 이 패턴을 볼 수 있습니다.

val newRegistry = CodecRegistries.fromRegistries(
CodecRegistries.fromCodecs(new MyEnumCodec()),
MongoClientSettings.getDefaultCodecRegistry()
)

이 섹션의 클래스 및 인터페이스에 대한 자세한 내용은 다음 API 설명서를 참조하세요.

CodecProvider 인터페이스는 Codec 인스턴스를 생성하여 CodecRegistry 인스턴스에 할당하는 추상 메서드를 포함합니다. CodecRegistry 인터페이스와 마찬가지로 CodecProvider 인터페이스는 Codec 인스턴스를 반환하는 get() 메서드를 정의합니다. BSON 라이브러리는 이러한 Codec 인스턴스를 사용하여 Scala와 BSON 데이터 유형 간의 인코딩을 수행합니다.

필드에 해당하는 Codec 객체가 필요한 클래스를 코드에 추가할 때 CodecProvider를 사용합니다. 각 필드에 고유한 Codec 인스턴스가 필요한 경우 클래스의 Codec 인스턴스를 인스턴스화하기 전에 각 필드에 대한 Codec 객체를 인스턴스화해야 합니다. get() 메서드의 CodecRegistry 매개변수를 사용하여 Codec이 의존하는 Codec 인스턴스를 생성자에 전달할 수 있습니다.

다음 예시는 CodecProvider 인터페이스를 구현하는 방법을 보여줍니다. 드라이버는 구현된 MonolightCodecProvider 인터페이스를 사용하여 Monolight 클래스에 대한 MonolightCodec 인스턴스를 생성합니다.

class MonolightCodecProvider extends CodecProvider {
override def get[T](clazz: Class[T], registry: CodecRegistry): Codec[T] = {
if (clazz == classOf[Monolight]) {
new MonolightCodec(registry).asInstanceOf[Codec[T]]
} else {
null
}
}
}

사용자 지정 클래스를 포함한 인터페이스의 전체 CodecProvider 구현 이 가이드 의 전체 사용자 지정 코덱 예제 섹션을 참조하세요.

이 섹션의 클래스 및 인터페이스에 대한 자세한 내용은 다음 API 설명서를 참조하세요.

이 섹션에서는 CodecCodecProvider 인터페이스를 구현하여 사용자 지정 Scala 클래스에 대한 인코딩 및 디코딩 로직을 정의하는 방법을 학습할 수 있습니다. 이 섹션에서는 사입 및 조회 작업을 수행하기 위해 사용자 지정 구현을 지정하고 사용하는 방법도 설명합니다.

다음 코드 스니펫은 사용자 정의 클래스 Monolight와 필드의 예시를 보여줍니다.

case class Monolight(
powerStatus: PowerStatus = PowerStatus.Off,
colorTemperature: Int = 0
)

Monolight 클래스에는 다음 필드가 포함되며, 각 필드에는 Codec 인터페이스 구현이 필요합니다.

  • powerStatus 표시등이 켜져 있는지 여부를 설명합니다.PowerStatusCodec 클래스는 PowerStatus 값을 BSON 부울로 인코딩합니다.

  • colorTemperature 조명의 색상을 설명하고 Int 값을 포함합니다. BSON 라이브러리에 포함된 IntegerCodec 클래스는 colorTemperature 값을 BSON 32비트 정수로 인코딩합니다.

다음 코드 예시는 Monolight 클래스에 대해 Codec 인터페이스를 구현하는 방법을 보여줍니다. 생성자는 CodecRegistry 인스턴스를 사용하여 Monolight 필드를 인코딩 및 디코딩하는 데 필요한 Codec 인스턴스를 조회합니다.

class MonolightCodec(registry: CodecRegistry) extends Codec[Monolight] {
private val powerStatusCodec: Codec[PowerStatus] =
registry.get(classOf[PowerStatus])
private val integerCodec: Codec[Integer] =
registry.get(classOf[Integer])
override def encode(writer: BsonWriter, value: Monolight,
encoderContext: EncoderContext): Unit = {
writer.writeStartDocument()
writer.writeName("powerStatus")
powerStatusCodec.encode(writer, value.powerStatus, encoderContext)
writer.writeName("colorTemperature")
integerCodec.encode(writer, value.colorTemperature, encoderContext)
writer.writeEndDocument()
}
override def decode(reader: BsonReader,
decoderContext: DecoderContext): Monolight = {
var powerStatus: PowerStatus = PowerStatus.Off
var colorTemperature: Int = 0
reader.readStartDocument()
while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
reader.readName() match {
case "powerStatus" =>
powerStatus = powerStatusCodec.decode(reader, decoderContext)
case "colorTemperature" =>
colorTemperature = integerCodec.decode(reader, decoderContext)
case "_id" =>
reader.readObjectId()
case _ =>
reader.skipValue()
}
}
reader.readEndDocument()
Monolight(powerStatus, colorTemperature)
}
override def getEncoderClass: Class[Monolight] = classOf[Monolight]
}

다음 코드 예시는 Monolight 클래스의 필드에 대한 Codec 인스턴스를 구성하고 사용자 지정 CodecProvider를 구현하는 방법을 보여줍니다.

class MonolightCodecProvider extends CodecProvider {
override def get[T](clazz: Class[T], registry: CodecRegistry): Codec[T] = {
if (clazz == classOf[Monolight]) {
new MonolightCodec(registry).asInstanceOf[Codec[T]]
} else {
null
}
}
}

get() 메서드는 드라이버가 Monolight 클래스에 대한 Codec를 요청할 때 새 MonolightCodec을 반환합니다. 메서드는 CodecRegistryMonolightCodec 생성자에 전달합니다. 그러면 MonolightCodecPowerStatusCodec, IntegerCodec 등 필드에 대한 Codec 인스턴스를 조회할 수 있습니다. 드라이버가 다른 클래스에 대한 Codec을 요청할 경우 메서드는 null을 반환합니다.

변환 로직을 정의한 후 다음 작업을 수행할 수 있습니다.

  • Monolight 클래스 인스턴스의 데이터를 MongoDB에 저장

  • MongoDB에서 Monolight 클래스의 인스턴스로 데이터 조회

다음 예시에서 MonolightCodecProvider 클래스를 withCodecRegistry() 메서드에 전달하여 MongoCollection 인스턴스에 할당합니다. 그리고 예시에서는 insertOne() 메서드를 호출하고 find() 메서드를 호출하여 저장된 Monolight 인스턴스를 반환하는 방식으로 새 Monolight 인스턴스를 컬렉션에 삽입합니다. 출력에는 조회된 Monolight 인스턴스가 표시됩니다. 이는 사용자 지정 코덱이 데이터를 성공적으로 인코딩하고 디코딩했음을 확인합니다.

object MonolightCodecExample {
def main(args: Array[String]): Unit = {
val uri = "<connection string URI>"
val mongoClient = MongoClient(uri)
val codecRegistry = CodecRegistries.fromRegistries(
CodecRegistries.fromCodecs(
new IntegerCodec(), new PowerStatusCodec()
),
CodecRegistries.fromProviders(new MonolightCodecProvider()),
MongoClientSettings.getDefaultCodecRegistry()
)
val database = mongoClient.getDatabase("codecs_example_products")
val collection: MongoCollection[Monolight] = database
.getCollection[Monolight]("monolights")
.withCodecRegistry(codecRegistry)
val myMonolight = Monolight(PowerStatus.On, 5200)
Await.result(
collection.insertOne(myMonolight).toFuture(),
Duration.Inf
)
val lights = Await.result(
collection.find().toFuture(),
Duration.Inf
)
println(lights)
mongoClient.close()
}
}
List(Monolight(On,5200))

이 섹션에 언급된 메서드 및 클래스에 대한 자세한 내용은 다음 API 문서를 참조하세요.