Overview
In this guide, you can learn how to use the Extended JSON data format when interacting with MongoDB documents.
JSON is a human-readable data format that represents the values of objects,
arrays, numbers, strings, booleans, and nulls. This format supports only a
subset of BSON data types, which is the format that MongoDB uses to store data. The
Extended JSON format supports more BSON types, defining a reserved
set of keys prefixed with "$
" to represent field type information that
directly corresponds to each type in BSON.
To learn more about JSON, BSON, and Extended JSON, see the JSON and BSON resource and Extended JSON MongoDB Server manual entry.
Extended JSON Formats
MongoDB Extended JSON provides string formats to represent BSON data. Each format conforms to the JSON RFC and meets specific use cases.
The following table describes each Extended JSON format:
Name | Description |
---|---|
Extended or Canonical | A string format that avoids loss of BSON type information during data conversions. This format prioritizes type preservation at the loss of human-readability and
interoperability with older formats. |
Relaxed | A string format that describes BSON documents with some type information loss. This format prioritizes human-readability and interoperability at the loss of
certain type information. |
Shell | A string format 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. |
Note
The Ruby 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.
Extended JSON Examples
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:
{ "_id": { "$oid": "573a1391f29313caabcd9637" }, "createdAt": { "$date": { "$numberLong": "1601499609" }}, "numViews": { "$numberLong": "36520312" } }
{ "_id": { "$oid": "573a1391f29313caabcd9637" }, "createdAt": { "$date": "2020-09-30T18:22:51.648Z" }, "numViews": 36520312 }
{ "_id": ObjectId("573a1391f29313caabcd9637"), "createdAt": ISODate("2020-09-30T18:22:51.648Z"), "numViews": NumberLong("36520312") }
Read Extended JSON
You can read an Extended JSON string into an Ruby array by calling
the BSON::ExtJSON.parse
method. This method parses an Extended
JSON string and returns an array containing the data.
The following example shows how you can read an Extended JSON string into a
array of hashes by using the parse
method:
require 'bson' ex_json = '''[ {"foo": [1, 2]}, {"bar": {"hello": "world"}}, {"code": { "$scope": {}, "$code": "function x() { return 1; }" }}, {"bin": { "$type": "80", "$binary": "AQIDBA==" }} ]''' doc = BSON::ExtJSON.parse(ex_json) puts doc.class puts doc
{"foo" => [1, 2]} {"bar" => {"hello" => "world"}} {"code" => #<BSON::CodeWithScope:0x0000000123f398e0 @javascript="function x() { return 1; }", @scope={}>} {"bin" => <BSON::Binary:0x7144 type=user data=0x01020304...>}
Write Extended JSON
You can write an Extended JSON string by using the as_extended_json
method. By default, this method returns the Extended JSON string in canonical
format, but you can specify relaxed or legacy formats by passing a mode
argument.
Note
Legacy Version
The legacy format option tells the Ruby driver to serialize BSON types with the MongoDB Extended JSON v1 format, which predates the current relaxed and canonical formats.
For more information see, the MongoDB Extended JSON v1 page in the Server manual.
The as_extended_json
method is available for several core and standard
library types, including Array
and Hash
. The following example creates
Extended JSON strings in the canonical, relaxed, and legacy formats, from an
array of hashes:
require 'bson' hash_array = [ { "foo" => [1, 2] }, { "bin" => BSON::Binary.new("\x01\x02\x03\x04", :user) }, { "number" => BSON::Int64.new(42) } ] json_string_canonical = hash_array.as_extended_json json_string_relaxed = hash_array.as_extended_json(mode: :relaxed) json_string_legacy = hash_array.as_extended_json(mode: :legacy) puts "canonical:\t #{json_string_canonical}" puts "relaxed:\t #{json_string_relaxed}" puts "legacy:\t\t #{json_string_legacy}"
canonical: [{"foo":[{"$numberInt":"1"},{"$numberInt":"2"}]},{"bin":{"$binary":{"base64":"AQIDBA==","subType":"80"}}},{"number":{"$numberLong":"42"}}] relaxed: [{"foo":[1,2]},{"bin":{"$binary":{"base64":"AQIDBA==","subType":"80"}}},{"number":42}] legacy: [{"foo":[1,2]},{"bin":{"$binary":"AQIDBA==","$type":"80"}},{"number":42}]
Additional Information
For more information, see the following resources: