-
Notifications
You must be signed in to change notification settings - Fork 10
DOCSP-51341: Extended JSON #116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 4 commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
.. _kotlin-sync-extended-json: | ||
|
||
============================ | ||
Work with Extended JSON Data | ||
============================ | ||
|
||
.. contents:: On this page | ||
:local: | ||
:backlinks: none | ||
:depth: 2 | ||
:class: singlecol | ||
|
||
.. facet:: | ||
:name: genre | ||
:values: reference | ||
|
||
.. meta:: | ||
:keywords: code examples, bson, relaxed, canonical | ||
|
||
.. sharedinclude:: dbx/extended-json.rst | ||
|
||
.. replacement:: driver-specific-text-extended | ||
|
||
.. replacement:: driver-specific-text-relaxed | ||
|
||
The {+driver-short+} uses Relaxed mode by default. | ||
|
||
.. replacement:: driver-specific-text-shell | ||
|
||
Read Extended JSON | ||
------------------ | ||
|
||
This section shows how to read Extended JSON values into {+language+} | ||
objects in the following ways: | ||
|
||
- :ref:`kotlin-sync-read-ejson-doc` | ||
- :ref:`kotlin-sync-read-ejson-jsonreader` | ||
|
||
.. _kotlin-sync-read-ejson-doc: | ||
|
||
Use the Document Classes | ||
~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
To read a Extended JSON string into a {+language+} document object, call | ||
the ``parse()`` static method from the ``Document`` or ``BsonDocument`` class. | ||
This method parses the Extended JSON string and stores its data in an instance of the specified | ||
document class. | ||
|
||
The following example uses the ``parse()`` method to read an Extended JSON string | ||
into a ``Document`` object: | ||
|
||
.. io-code-block:: | ||
:copyable: | ||
|
||
.. input:: /includes/data-formats/ext-json.kt | ||
:language: kotlin | ||
:start-after: start-read-doc | ||
:end-before: end-read-doc | ||
:dedent: | ||
|
||
.. output:: | ||
:visible: false | ||
|
||
Document{{_id=507f1f77bcf86cd799439011, myNumber=4794261}} | ||
|
||
.. _kotlin-sync-read-ejson-jsonreader: | ||
|
||
Use the JsonReader Class | ||
~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
To read an Extended JSON string into {+language+} objects without using | ||
the {+driver-short+}'s document classes, use the BSON library's ``JsonReader`` class. | ||
This class contains methods to sequentially parse the fields and values | ||
of the Extended JSON string and return them as {+language+} objects. | ||
The driver's document classes also use this class to parse Extended JSON. | ||
|
||
The following code uses methods provided by the ``JsonReader`` class to convert | ||
an Extended JSON string into {+language+} objects: | ||
|
||
.. io-code-block:: | ||
:copyable: | ||
|
||
.. input:: /includes/data-formats/ext-json.kt | ||
:language: kotlin | ||
:start-after: start-read-bson | ||
:end-before: end-read-bson | ||
:dedent: | ||
|
||
.. output:: | ||
:visible: false | ||
|
||
507f1f77bcf86cd799439011 is type: org.bson.types.ObjectId | ||
4794261 is type: kotlin.Long | ||
|
||
Write Extended JSON | ||
------------------- | ||
|
||
This section shows how to write Extended JSON values from {+language+} | ||
objects in the following ways: | ||
|
||
- :ref:`kotlin-sync-write-ejson-doc` | ||
- :ref:`kotlin-sync-write-ejson-jsonwriter` | ||
|
||
.. _kotlin-sync-write-ejson-doc: | ||
|
||
Use the Document Classes | ||
~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
To write an Extended JSON string from a ``Document`` or ``BsonDocument`` | ||
object, call the ``toJson()`` method. You can pass this method a | ||
``JsonWriterSettings`` object parameter to specify the Extended JSON format. | ||
|
||
The following example writes ``Document`` data as Relaxed mode Extended | ||
JSON: | ||
|
||
.. io-code-block:: | ||
:copyable: | ||
|
||
.. input:: /includes/data-formats/ext-json.kt | ||
:language: kotlin | ||
:start-after: start-write-doc | ||
:end-before: end-write-doc | ||
:dedent: | ||
|
||
.. output:: | ||
:visible: false | ||
|
||
{"_id": {"$oid": "507f1f77bcf86cd799439012"}, "createdAt": {"$date": "2020-09-30T21:00:09Z"}, "myNumber": 4794261} | ||
|
||
.. _kotlin-sync-write-ejson-jsonwriter: | ||
|
||
Use the JsonWriter Class | ||
~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
To output an Extended JSON string from data stored in {+language+} objects, you can use | ||
the BSON library's ``JsonWriter`` class. To construct a ``JsonWriter`` object, | ||
pass a subclass of a Java ``Writer`` to specify how you want to output the Extended | ||
JSON. Optionally, you can pass a ``JsonWriterSettings`` instance to specify options, | ||
such as the Extended JSON format. By default, ``JsonWriter`` uses the Relaxed mode | ||
format. The {+driver-short+}'s document classes also use this class to convert BSON | ||
to Extended JSON. | ||
|
||
The following example uses a ``JsonWriter`` object to create | ||
Canonical mode Extended JSON string values and output them to ``System.out``: | ||
|
||
.. io-code-block:: | ||
:copyable: | ||
|
||
.. input:: /includes/data-formats/ext-json.kt | ||
:language: kotlin | ||
:start-after: start-write-bson | ||
:end-before: end-write-bson | ||
:dedent: | ||
|
||
.. output:: | ||
:visible: false | ||
|
||
{"_id": {"$oid": "507f1f77bcf86cd799439012"}, "myNumber": {"$numberLong": "11223344"}} | ||
|
||
Custom BSON Type Conversion | ||
--------------------------- | ||
|
||
In addition to specifying the Extended JSON output format, you | ||
can further customize the output by adding converters to your | ||
``JsonWriterSettings`` object. These converter methods specify logic | ||
for handling different data types during the conversion process. | ||
|
||
The following example converts the same document as the :ref:`kotlin-sync-write-ejson-doc` | ||
example. However, this example defines the ``objectIdConverter()`` and ``dateTimeConverter()`` | ||
converter methods in a ``JsonWriterSettings`` object to simplify the Relaxed mode | ||
Extended JSON output: | ||
|
||
.. io-code-block:: | ||
:copyable: | ||
|
||
.. input:: /includes/data-formats/ext-json.kt | ||
:language: kotlin | ||
:start-after: start-custom-conversion | ||
:end-before: end-custom-conversion | ||
:dedent: | ||
|
||
.. output:: | ||
:visible: false | ||
|
||
{"_id": "507f1f77bcf86cd799439012", "createdAt": "2020-09-30T21:00:09Z", "myNumber": 4794261} | ||
|
||
API Documentation | ||
----------------- | ||
|
||
To learn more about any of the methods or types discussed in this | ||
guide, see the following API documentation: | ||
|
||
- `Document <{+api-root+}/bson/org/bson/Document.html>`__ | ||
- `Document.parse() <{+api-root+}/bson/org/bson/Document.html#parse(java.lang.String)>`__ | ||
- `JsonReader <{+api-root+}/bson/org/bson/json/JsonReader.html>`__ | ||
- `JsonWriter <{+api-root+}/bson/org/bson/json/JsonWriter.html>`__ | ||
- `Document.toJson() <{+api-root+}/bson/org/bson/Document.html#toJson()>`__ | ||
- `JsonWriterSettings <{+api-root+}/bson/org/bson/json/JsonWriterSettings.html>`__ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package org.example | ||
|
||
import org.bson.json.JsonWriter | ||
import org.bson.json.JsonWriterSettings | ||
import java.util.Date | ||
import org.bson.Document | ||
import org.bson.json.JsonMode | ||
import org.bson.json.JsonReader | ||
import org.bson.types.ObjectId | ||
import java.time.Instant | ||
import java.time.ZoneOffset | ||
import java.time.format.DateTimeFormatter | ||
import java.io.BufferedWriter | ||
import java.io.OutputStreamWriter | ||
|
||
fun main() { | ||
|
||
// start-read-doc | ||
val ejsonStr = """ | ||
{ | ||
"_id": { "$${"oid"}": "507f1f77bcf86cd799439011" }, | ||
"myNumber": { "$${"numberLong"}": "4794261" } | ||
} | ||
""".trimIndent() | ||
|
||
val doc = Document.parse(ejsonStr) | ||
println(doc) | ||
// end-read-doc | ||
|
||
// start-read-bson | ||
val string = """ | ||
{ | ||
"_id": { "$${"oid"}": "507f1f77bcf86cd799439011" }, | ||
"myNumber": { "$${"numberLong"}": "4794261" } | ||
} | ||
""".trimIndent() | ||
|
||
val jsonReader = JsonReader(string) | ||
jsonReader.readStartDocument() | ||
|
||
// Reads the "_id" field value | ||
jsonReader.readName("_id") | ||
val id = jsonReader.readObjectId() | ||
|
||
// Reads the "myNumber" field value | ||
jsonReader.readName("myNumber") | ||
val myNumber = jsonReader.readInt64() | ||
|
||
jsonReader.readEndDocument() | ||
|
||
println("$id is type: ${id::class.qualifiedName}") | ||
println("$myNumber is type: ${myNumber::class.qualifiedName}") | ||
|
||
jsonReader.close() | ||
// end-read-bson | ||
|
||
// start-write-doc | ||
val doc = Document() | ||
.append("_id", ObjectId("507f1f77bcf86cd799439012")) | ||
.append("createdAt", Date.from(Instant.ofEpochMilli(1601499609000L))) | ||
.append("myNumber", 4794261) | ||
|
||
val settings = JsonWriterSettings.builder() | ||
.outputMode(JsonMode.RELAXED) | ||
.build() | ||
|
||
println(myDoc.toJson(settings)) | ||
// end-write-doc | ||
|
||
// start-write-bson | ||
val settings = JsonWriterSettings.builder() | ||
.outputMode(JsonMode.EXTENDED) | ||
.build() | ||
|
||
JsonWriter(BufferedWriter(OutputStreamWriter(System.out)), settings).use { jsonWriter -> | ||
jsonWriter.writeStartDocument() | ||
jsonWriter.writeName("_id") | ||
jsonWriter.writeObjectId(ObjectId("507f1f77bcf86cd799439012")) | ||
jsonWriter.writeName("myNumber") | ||
jsonWriter.writeInt64(11223344L) | ||
jsonWriter.writeEndDocument() | ||
jsonWriter.flush() | ||
} | ||
// end-write-bson | ||
|
||
// start-custom-conversion | ||
val settings = JsonWriterSettings.builder() | ||
.outputMode(JsonMode.RELAXED) | ||
.objectIdConverter { value, writer -> | ||
writer.writeString(value.toHexString()) | ||
} | ||
.dateTimeConverter { value, writer -> | ||
val zonedDateTime = Instant.ofEpochMilli(value).atZone(ZoneOffset.UTC) | ||
writer.writeString(DateTimeFormatter.ISO_DATE_TIME.format(zonedDateTime)) | ||
} | ||
.build() | ||
|
||
val doc = Document() | ||
.append("_id", ObjectId("507f1f77bcf86cd799439012")) | ||
.append("createdAt", Date.from(Instant.ofEpochMilli(1601499609000L))) | ||
.append("myNumber", 4794261) | ||
|
||
println(doc.toJson(settings)) | ||
// end-custom-conversion | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.