Docs Menu
Docs Home
/ / /
Kotlin Coroutine
/ /

Document Data Format: Extended JSON

On this page

  • Overview
  • Extended JSON Formats
  • Extended JSON Examples
  • Read Extended JSON
  • Using the Document Classes
  • Using the BSON Library
  • Write Extended JSON
  • Using the Document Classes
  • Using the BSON Library
  • Custom BSON Type Conversion

In this guide, you can learn how to use the Extended JSON format in the MongoDB Kotlin driver.

JSON is a data format that represents the values of objects, arrays, numbers, strings, booleans, and nulls. The Extended JSON format defines a reserved set of keys prefixed with "$" to represent field type information that directly corresponds to each type in BSON, the format that MongoDB uses to store data.

This guide explains the following topics:

  • The different MongoDB Extended JSON formats

  • How to use the BSON library to convert between Extended JSON and Kotlin objects

  • How to create a custom conversion of BSON types

For more information on the difference between these formats, see our article on JSON and BSON.

MongoDB Extended JSON features different string formats to represent BSON data. Each of the different formats conform to the JSON RFC and meet specific use cases. The extended format, also known as the canonical format, features specific representations for every BSON type for bidirectional conversion without loss of information. The Relaxed mode format is more concise and closer to ordinary JSON, but does not represent all the type information such as the specific byte size of number fields.

See the following table to see a description of each format:

Also known as the canonical format, this JSON representation avoids loss of BSON type information.
This format prioritizes type preservation at the loss of human-readability and interoperability with older formats.
Relaxed Mode
JSON representation that describes BSON documents with some type information loss.
This format prioritizes human-readability and interoperability at the loss of certain type information.
JSON representation that matches the syntax used in the MongoDB shell.
This format prioritizes compatibility with the MongoDB shell which often uses JavaScript functions to represent types.
Deprecated. This representation is the legacy format that fully conforms to the JSON RFC which allows any JSON parser to read the type information.
The legacy API uses this format.


The driver parses the $uuid Extended JSON type from a string to a BsonBinary object of binary subtype 4. For more information about $uuid field parsing, see the special rules for parsing $uuid fields section in the extended JSON specification.

For more detailed information on these formats, see the following resources:

The following examples show a document containing an ObjectId, date, and long number field represented in each Extended JSON format. Click the tab that corresponds to the format of the example you want to see:

You can read an Extended JSON string into a Kotlin document object by calling the parse() static method from either the Document or BsonDocument class, depending on which object type you need. This method parses the Extended JSON string in any of the formats and returns an instance of that class containing the data.

The following example shows how you can use the Document class to read an example Extended JSON string into a Document object using the parse() method:

val ejsonStr = """
{ "_id": { "${"$"}oid": "507f1f77bcf86cd799439011"},
"myNumber": {"${"$"}numberLong": "4794261" }}
val doc = Document.parse(ejsonStr)
Document{{_id=507f1f77bcf86cd799439011, myNumber=4794261}}

For more information, see our Fundamentals page on Documents.

You can also read an Extended JSON string into Kotlin objects without using the MongoDB Kotlin driver's document classes by using the JsonReader class. This class contains methods to sequentially parse the fields and values in any format of the Extended JSON string, and returns them as Kotlin objects. The driver's document classes also use this class to parse Extended JSON.

The following code example shows how you can use the JsonReader class to convert an Extended JSON string into Kotlin objects:

val ejsonStr = """
{ "_id": { "${"$"}oid": "507f1f77bcf86cd799439011"},
"myNumber": {"${"$"}numberLong": "4794261" }}
val jsonReader = JsonReader(ejsonStr)
val id = jsonReader.readObjectId()
val myNumber = jsonReader.readInt64()
println(id.toString() + " is type: " +
println(myNumber.toString() + " is type: " +
507f1f77bcf86cd799439011 is type: org.bson.types.ObjectId
4794261 is type: java.lang.Long

For more information, see the JsonReader API Documentation.

You can write an Extended JSON string from an instance of Document or BsonDocument by calling the toJson() method, optionally passing it an instance of JsonWriterSettings to specify the Extended JSON format.

In this example, we output the Extended JSON in the Relaxed mode format.

val myDoc = Document().append("_id", ObjectId("507f1f77bcf86cd799439012"))
.append("myNumber", 11223344)
val settings = JsonWriterSettings.builder().outputMode(JsonMode.RELAXED).build()
{"_id": {"$oid": "507f1f77bcf86cd799439012"}, "myNumber": 11223344}

You can also output an Extended JSON string from data in Kotlin objects using the BSON library with the JsonWriter class. To construct an instance of JsonWriter, pass a subclass of a Java Writer to specify how you want to output the Extended JSON. You can optionally pass a JsonWriterSettings instance to specify options such as the Extended JSON format. By default, the JsonWriter uses the Relaxed mode format. The MongoDB Kotlin driver's document classes also use this class to convert BSON to Extended JSON.

The following code example shows how you can use JsonWriter to create an Extended JSON string and output it to System.out. We specify the format by passing the outputMode() builder method the JsonMode.EXTENDED constant:

val settings = JsonWriterSettings.builder().outputMode(JsonMode.EXTENDED).build()
JsonWriter(BufferedWriter(OutputStreamWriter(System.out)), settings).use { jsonWriter ->
jsonWriter.writeObjectId("_id", ObjectId("507f1f77bcf86cd799439012"))
jsonWriter.writeInt64("myNumber", 11223344)
{"_id": {"$oid": "507f1f77bcf86cd799439012"}, "myNumber": {"$numberLong": "11223344"}}

For more information about the methods and classes mentioned in this section, see the following API Documentation:

In addition to specifying the outputMode() to format the JSON output, you can further customize the output by adding converters to your JsonWriterSettings.Builder. These converter methods detect the Kotlin types and execute the logic defined by the Converter passed to them.

The following sample code shows how to append converters, defined as lambda expressions, to simplify the Relaxed mode JSON output.

val settings = JsonWriterSettings.builder()
.objectIdConverter { value, writer -> writer.writeString(value.toHexString()) }
.timestampConverter { value, writer ->
val ldt = LocalDateTime.ofInstant(Instant.ofEpochSecond(value.time.toLong()), ZoneOffset.UTC)
val doc = Document()
.append("_id", ObjectId("507f1f77bcf86cd799439012"))
.append("createdAt", BsonTimestamp(1601516589,1))
.append("myNumber", 4794261)
{"_id": "507f1f77bcf86cd799439012", "createdAt": "2020-10-01T01:43:09", "myNumber": 4794261}
// Without specifying the converters, the Relaxed mode JSON output
// should look something like this:
{"_id": {"$oid": "507f1f77bcf86cd799439012"}, "createdAt": {"$timestamp": {"t": 1601516589, "i": 1}}, "myNumber": 4794261}

For more information about the methods and classes mentioned in this section, see the following API Documentation:

← Document Data Format: BSON