Docs Menu
Docs Home
/ / /
Ruby Driver
/

Extended JSON

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.

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.

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")
}

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...>}

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}]

For more information, see the following resources:

Back

BSON

On this page