Docs Menu
Docs Home
/ / /
Scala
/

Extended JSON

On this page

  • Overview
  • Writing JSON
  • Reading JSON
  • Reading and Writing JSON Directly
  • Reading and Writing JSON with CustomSettings

The Scala driver supports reading and writing of BSON documents represented as MongoDB Extended JSON. Both of the following variants are supported:

  • Strict Mode: representations of BSON types that conform to the JSON RFC. This is the format that mongoexport produces and mongoimport consumes.

  • Shell Mode: a superset of JSON that the MongoDB shell can parse.

Furthermore, the Document type provides two sets of convenience methods for this purpose:

  • Document.toJson(): a set of overloaded methods that convert a Document instance to a JSON string

  • Document(<json>): a set of overloaded static factory methods that convert a JSON string to a Document instance

Consider the task of implementing a mongoexport-like tool by using the driver:

val fileName = // initialize to the path of the file to write to
val collection = // initialize the collection from which you want to query
val writer: PrintWriter = new PrintWriter(fileName)
collection.find().subscribe(
(doc: Document) => output.write(s"${doc.toJson}\r\n"),
(t: Throwable) => // handle failure,
() => output.close())

The Document.toJson() method constructs an instance of a JsonWriter with its default settings, which writes in strict mode with no new lines or indentation.

You can override this default behavior by using one of the overloads of toJson(). As an example, consider the task of writing a JSON string that can be copied and pasted into the MongoDB shell:

import java.text.SimpleDateFormat
val fmt = new SimpleDateFormat("dd/MM/yy")
val first = fmt.parse("01/01/2014")
val second = fmt.parse("01/01/2015")
val doc = Document("startDate" -> Document("$gt" -> first, "$lt" -> second))
println(doc.toJson(new JsonWriterSettings(JsonMode.SHELL)))

This code snippet will print out MongoDB shell-compatible JSON, which can then be pasted into the shell:

{ "startDate" : { "$gt" : ISODate("2014-01-01T05:00:00.000Z"), "$lt" : ISODate("2015-01-01T05:00:00.000Z") } }

Consider the task of implementing a mongoimport-like tool by using driver:

import scala.io.Source
val fileName = // initialize to the path of the file to read from
val collection = // initialize the collection from which you want to import to
try {
for (json <- Source.fromFile(fileName).getLines()) {
collection.insertOne(Document(json)).head()
}
} catch {
case ex: Exception => println("Bummer, an exception happened.")
}

The Document(<json>) companion helper method constructs an instance of a JsonReader with the given string and returns an instance of an equivalent Document instance. JsonReader automatically detects the JSON flavor in the string, so you do not need to specify it.

If you do not need a document and only want to deal with JSON, you can use a JsonObject to read and write JSON directly. JsonObject is a wrapper class that takes in a String in the constructor and returns the String in the getJson() method. Reading and writing JSON directly is more efficient than constructing a Document first and then calling toJson(), and it is also more efficient than calling Document#parse().

The codec responsible for reading/writing JSON, JsonObjectCodec, is part of the default registry, so doing this is very simple and demonstrated by the following example:

val database: MongoDatabase = mongoClient.getDatabase("mydb")
val collection: MongoCollection[JsonObject] = database.getCollection("test")
collection.insertOne(new JsonObject("{hello: 1}")).printResults()
val jsonObject: SingleObservable[JsonObject] = collection.find.first()

You can also provide custom JsonWriterSettings to the JsonObjectCodec, by constructing the codec yourself and then creating a registry:

val codecRegistry =
fromRegistries(
fromCodecs(new JsonObjectCodec(JsonWriterSettings
.builder()
.outputMode(JsonMode.EXTENDED)
.build())),
DEFAULT_CODEC_REGISTRY
)
val database: MongoDatabase = mongoClient.getDatabase("mydb").withCodecRegistry(codecRegistry)
val collection: MongoCollection[JsonObject] = database.getCollection("test")
collection.insertOne(new JsonObject("{hello: 1}")).printResults()
val jsonObject: SingleObservable[JsonObject] = collection.find.first()

Back

Macros