Extended JSON
On this page
Overview
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 aDocument
instance to a JSON stringDocument(<json>)
: a set of overloaded static factory methods that convert a JSON string to aDocument
instance
Writing JSON
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") } }
Reading JSON
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.
Reading and Writing JSON Directly
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()
Reading and Writing JSON with CustomSettings
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()