Skip to content

DOCSP-47071: Extended JSON #268

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 4 commits into from
Jun 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion source/data-formats.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Specialized Data Formats
Decimal128 </data-formats/decimal128>
BSON </data-formats/modeling-bson-data>
Time Series </data-formats/time-series>
Extended JSON </data-formats/extended-json>

Overview
--------
Expand All @@ -36,4 +37,5 @@ guides:
- :ref:`php-custom-types`
- :ref:`php-decimal128`
- :ref:`php-bson`
- :ref:`php-time-series`
- :ref:`php-time-series`
- :ref:`php-extended-json`
203 changes: 203 additions & 0 deletions source/data-formats/extended-json.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
.. _php-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

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.

Extended JSON Formats
---------------------

MongoDB Extended JSON features two string formats to represent BSON data.
Each format conforms to the `JSON RFC <https://www.rfc-editor.org/rfc/rfc8259>`__
and meets specific use cases.

The following table describes each Extended JSON format:

.. list-table::
:header-rows: 1
:stub-columns: 1
:widths: 10 40

* - Name
- Description

* - **Canonical** or **Extended**
- | 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.
Comment on lines +33 to +53
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYA, I went and made a sharedinclude for a lot of this boilerplate – see the C# Extended JSON page for an example.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the shell extended json format doesn't apply here, I won't use the sharedinclude


* - **Relaxed Mode**
- | 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.

To learn more about JSON, BSON, and Extended JSON, see the
`JSON and BSON <https://www.mongodb.com/resources/basics/json-and-bson>`__ resource
and :manual:`Extended JSON </reference/mongodb-extended-json/>` {+mdb-server+} manual
entry.

.. _php-extended_json_example:

Extended JSON Examples
~~~~~~~~~~~~~~~~~~~~~~

The following example shows a document containing an ``ObjectId``, date, and long
number field represented in the Extended JSON format. Select the :guilabel:`Canonical`
or the :guilabel:`Relaxed Mode` tab to view the sample document in each Extended
JSON format:

.. tabs::

.. tab:: Canonical
:tabid: canonical-format

.. code-block:: json

{
"_id": { "$oid": "573a1391f29313caabcd9637" },
"createdAt": { "$date": { "$numberLong": "1601499609" }},
"numViews": { "$numberLong": "36520312" }
}

.. tab:: Relaxed Mode
:tabid: relaxed-mode-format

.. code-block:: json

{
"_id": { "$oid": "573a1391f29313caabcd9637" },
"createdAt": { "$date": "2020-09-30T18:22:51.648Z" },
"numViews": 36520312
}

Write Extended JSON
-------------------

You can write an Extended JSON string from a BSON document object by using the
``toRelaxedExtendedJSON()`` and ``toCanonicalExtendedJSON()`` methods.

The following example outputs a BSON document in both Relaxed and Canonical
Extended JSON formats:

.. io-code-block::
:copyable:

.. input:: /includes/extended-json.php
:start-after: start-write-extended
:end-before: end-write-extended
:language: php
:dedent:

.. output::
:visible: false

Relaxed format: { "foo" : [ 1, 2 ], "bar" : { "hello" : "world" }, "code" :
{ "$code" : "function x() { return 1; }", "$scope" : { } }, "date" : { } }
Canonical format: { "foo" : [ { "$numberInt" : "1" }, { "$numberInt" : "2" } ],
"bar" : { "hello" : "world" }, "code" : { "$code" : "function x() { return 1; }",
"$scope" : { } }, "date" : { } }

Read Extended JSON
------------------

You can read an Extended JSON string into a PHP value by calling
the ``json_decode()`` method, which converts Extended JSON to a
PHP array or object. Pass the following arguments to ``json_decode()``:

- Extended JSON string to read.
- Boolean value that indicates whether you want to return
an array value. If set to ``false``, the method returns an
object value.

The following example converts an Extended JSON string value
to a PHP array:

.. io-code-block::
:copyable:

.. input:: /includes/extended-json.php
:start-after: start-read-extended
:end-before: end-read-extended
:language: php
:dedent:

.. output::
:visible: false

Array
(
[foo] => Array
(
[0] => Array
(
[$numberInt] => 1
)

[1] => Array
(
[$numberInt] => 2
)

)

[bar] => Array
(
[hello] => world
)

[code] => Array
(
[$code] => function x() { return 1; }
[$scope] => Array
(
)

)

[bin] => Array
(
[$binary] => Array
(
[base64] => AQIDBA==
[subType] => 00
)

)

)

API Documentation
-----------------

To learn more about the methods discussed on this page, see
the following {+extension-short+} API documentation:

- :php:`MongoDB\BSON\Document::toRelaxedExtendedJSON() <mongodb-bson-document.torelaxedextendedjson>`
- :php:`MongoDB\BSON\Document::toCanonicalExtendedJSON() <mongodb-bson-document.tocanonicalextendedjson>`
- :php:`json_decode() <function.json-decode>`
33 changes: 33 additions & 0 deletions source/includes/extended-json.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

require 'vendor/autoload.php';

// start-write-extended
$doc = [
'foo' => [1, 2],
'bar' => ['hello' => 'world'],
'code' => new MongoDB\BSON\Javascript('function x() { return 1; }', []),
'date' => new DateTime('2024-07-20 10:30:00')
];

echo 'Relaxed format: ' , MongoDB\BSON\Document::fromPHP($doc)->toRelaxedExtendedJSON(), PHP_EOL;
echo 'Canonical format: ' , MongoDB\BSON\Document::fromPHP($doc)->toCanonicalExtendedJSON(), PHP_EOL;
// end-write-extended

// start-read-extended
$ejsonStr = '{
"foo": [
{ "$numberInt": "1" },
{ "$numberInt": "2" }
],
"bar": { "hello": "world" },
"code": {
"$code": "function x() { return 1; }",
"$scope": {}
},
"bin": { "$binary": { "base64": "AQIDBA==", "subType": "00" } }
}';

$decodedJson = json_decode($ejsonStr, true);
print_r($decodedJson);
// end-read-extended
Loading