mirror of
https://github.com/macintoshplus/mongo-php-driver.git
synced 2026-03-30 21:02:08 +02:00
503 lines
19 KiB
ReStructuredText
503 lines
19 KiB
ReStructuredText
===============================
|
|
Persistence in Hippo and Phongo
|
|
===============================
|
|
|
|
This document discusses the methods how compound structures (documents,
|
|
arrays, objects) are persisted through the drivers. And how they are brought
|
|
back into PHP land.
|
|
|
|
Serialization to BSON
|
|
=====================
|
|
|
|
Arrays
|
|
------
|
|
|
|
If an array is a *packed array* — i.e. the keys start at 0 and are sequential
|
|
without gaps: **BSON array**.
|
|
|
|
If the array is not packed — i.e. having associative (string) keys, the keys
|
|
don't start at 0, or when there are gaps:: **BSON object**
|
|
|
|
A top-level (root) document, **always** serializes as a BSON document.
|
|
|
|
Examples
|
|
~~~~~~~~
|
|
|
|
These serialize as a BSON array::
|
|
|
|
[ 8, 5, 2, 3 ] => [ 8, 5, 2, 3 ]
|
|
[ 0 => 4, 1 => 9 ] => [ 4, 9 ]
|
|
|
|
|
|
These serialize as a BSON document::
|
|
|
|
[ 0 => 1, 2 => 8, 3 => 12 ] => { "0" : 1, "2" : 8, "3" : 12 }
|
|
[ "foo" => 42 ] => { "foo" : 42 }
|
|
[ 1 => 9, 0 => 10 ] => { "1" : 9, "0" : 10 }
|
|
|
|
Note that the five examples are *extracts* of a full document, and represent
|
|
only **one** value inside a document.
|
|
|
|
Objects
|
|
-------
|
|
|
|
If an object is of the *stdClass*, serialize as a **BSON document**.
|
|
|
|
If an object is a supported class that implements ``MongoDB\BSON\Type``, then
|
|
use the BSON serialization logic for that specific type. ``MongoDB\BSON\Type``
|
|
instances (excluding ``MongoDB\BSON\Serializable``) may only be serialized as
|
|
a document field value. Attempting to serialize such an object as a root
|
|
document will throw a ``MongoDB\Driver\Exception\UnexpectedValueException``.
|
|
|
|
If an object is of an unknown class implementing the ``MongoDB\BSON\Type``
|
|
interface, then throw a ``MongoDB\Driver\Exception\UnexpectedValueException``.
|
|
|
|
If an object is of any other class, without implementing any special
|
|
interface, serialize as a **BSON document**. Keep only *public* properties,
|
|
and ignore *protected* and *private* properties.
|
|
|
|
If an object is of a class that implements the ``MongoDB\BSON\Serializable``
|
|
interface, call ``bsonSerialize`` and use the returned array or ``stdClass`` to
|
|
serialize as a BSON document or array. The BSON type will be determined by the
|
|
following:
|
|
|
|
1. Root documents must be serialized as a BSON document.
|
|
2. ``MongoDB\BSON\Persistable`` objects must be serialized as a BSON document.
|
|
3. If ``bsonSerialize`` returns a packed array, serialize as a BSON array.
|
|
4. If ``bsonSerialize`` returns a non-packed array or ``stdClass``, serialize as
|
|
a BSON document.
|
|
5. If ``bsonSerialize`` did not return an array or ``stdClass``, throw an
|
|
``MongoDB\Driver\Exception\UnexpectedValueException`` exception.
|
|
|
|
If an object is of a class that implements the ``MongoDB\BSON\Persistable``
|
|
interface (which implies ``MongoDB\BSON\Serializable``), obtain the properties
|
|
in a similar way as in the previous paragraphs, but *also* add an additional
|
|
property ``__pclass`` as a Binary value, with subtype ``0x80`` and data bearing
|
|
the fully qualified class name of the object that is being serialized.
|
|
|
|
The ``__pclass`` property is added to the array or object returned by
|
|
``bsonSerialize``, which means it will overwrite any ``__pclass`` key/property
|
|
in the ``bsonSerialize`` return value. If you want to avoid this behaviour and
|
|
set your own ``__pclass`` value, you must **not** implement
|
|
``MongoDB\BSON\Persistable`` and should instead implement
|
|
``MongoDB\BSON\Serializable`` directly.
|
|
|
|
Examples
|
|
~~~~~~~~
|
|
|
|
::
|
|
|
|
stdClass {
|
|
public $foo = 42;
|
|
} => { "foo" : 42 }
|
|
|
|
MyClass {
|
|
public $foo = 42;
|
|
protected $prot = "wine";
|
|
private $fpr = "cheese";
|
|
} => { "foo" : 42 }
|
|
|
|
AnotherClass1 implements MongoDB\BSON\Serializable {
|
|
public $foo = 42;
|
|
protected $prot = "wine";
|
|
private $fpr = "cheese";
|
|
function bsonSerialize() {
|
|
return [ 'foo' => $this->foo, 'prot' => $this->prot ];
|
|
}
|
|
} => { "foo" : 42, "prot" : "wine" }
|
|
|
|
AnotherClass2 implements MongoDB\BSON\Serializable {
|
|
public $foo = 42;
|
|
function bsonSerialize() {
|
|
return $this;
|
|
}
|
|
} => MongoDB\Driver\Exception\UnexpectedValueException("bsonSerialize() did not return an array or stdClass")
|
|
|
|
AnotherClass3 implements MongoDB\BSON\Serializable {
|
|
private $elements = [ 'foo', 'bar' ];
|
|
function bsonSerialize() {
|
|
return $this->elements;
|
|
}
|
|
} => { "0" : "foo", "1" : "bar" }
|
|
|
|
ContainerClass implements MongoDB\BSON\Serializable {
|
|
public $things = AnotherClass4 implements MongoDB\BSON\Serializable {
|
|
private $elements = [ 0 => 'foo', 2 => 'bar' ];
|
|
function bsonSerialize() {
|
|
return $this->elements;
|
|
}
|
|
}
|
|
function bsonSerialize() {
|
|
return [ 'things' => $this->things ];
|
|
}
|
|
} => { "things" : { "0" : "foo", "2" : "bar" } }
|
|
|
|
ContainerClass implements MongoDB\BSON\Serializable {
|
|
public $things = AnotherClass5 implements MongoDB\BSON\Serializable {
|
|
private $elements = [ 0 => 'foo', 2 => 'bar' ];
|
|
function bsonSerialize() {
|
|
return array_values($this->elements);
|
|
}
|
|
}
|
|
function bsonSerialize() {
|
|
return [ 'things' => $this->things ];
|
|
}
|
|
} => { "things" : [ "foo", "bar" ] }
|
|
|
|
ContainerClass implements MongoDB\BSON\Serializable {
|
|
public $things = AnotherClass6 implements MongoDB\BSON\Serializable {
|
|
private $elements = [ 'foo', 'bar' ];
|
|
function bsonSerialize() {
|
|
return (object) $this->elements;
|
|
}
|
|
}
|
|
function bsonSerialize() {
|
|
return [ 'things' => $this->things ];
|
|
}
|
|
} => { "things" : { "0" : "foo", "1" : "bar" } }
|
|
|
|
UpperClass implements MongoDB\BSON\Persistable {
|
|
public $foo = 42;
|
|
protected $prot = "wine";
|
|
private $fpr = "cheese";
|
|
function bsonSerialize() {
|
|
return [ 'foo' => $this->foo, 'prot' => $this->prot ];
|
|
}
|
|
} => { "foo" : 42, "prot" : "wine", "__pclass" : { "$type" : "80", "$binary" : "VXBwZXJDbGFzcw==" } }
|
|
|
|
|
|
Deserialization from BSON
|
|
=========================
|
|
|
|
Compound Types
|
|
--------------
|
|
|
|
For compound types, there are three data types:
|
|
|
|
- ``root``: refers to the top-level BSON document *only*
|
|
- ``document``: refers to embedded BSON documents *only*
|
|
- ``array``: refers to a BSON array
|
|
|
|
Each of those three data types can be mapped against different PHP types. The
|
|
possible mapping values are:
|
|
|
|
- *not set* or ``NULL`` — this is the default.
|
|
|
|
- A BSON array will be deserialized as a PHP ``array``.
|
|
- A BSON document (root or embedded) without a ``__pclass`` property [1]_
|
|
becomes a PHP ``stdClass`` object, with each BSON document key set as a
|
|
public ``stdClass`` property.
|
|
- A BSON document (root or embedded) with a ``__pclass`` property [1]_ becomes
|
|
a PHP object of the class name as defined by the ``__pclass`` property.
|
|
|
|
If the named class implements the ``MongoDB\BSON\Persistable``
|
|
interface, then the properties of the BSON document, including the
|
|
``__pclass`` property, are sent as an associative array to the
|
|
``bsonUnserialize`` function to initialise the object's properties.
|
|
|
|
If the named class does not exist or does not implement the
|
|
``MongoDB\BSON\Persistable`` interface, ``stdClass`` will be used and
|
|
each BSON document key (including ``__pclass``) will be set as a public
|
|
``stdClass`` property.
|
|
|
|
- ``"array"`` — turns a BSON array or BSON document into a PHP array. There will
|
|
be no special treatment of a ``__pclass`` property [1]_, but it may be set as
|
|
an element in the returned array if it was present in the BSON document.
|
|
|
|
- ``"object"`` or ``"stdClass"`` — turns a BSON array or BSON document into a
|
|
``stdClass`` object. There will be no special treatment of a ``__pclass``
|
|
property [1]_, but it may be set as a public property in the returned object
|
|
if it was present in the BSON document.
|
|
|
|
- ``any other string`` — defines the class name that the BSON array or BSON
|
|
object should be deserialized as. For BSON objects that include ``__pclass``
|
|
properties, that class will take priority.
|
|
|
|
If the named class does not exist, is not concrete (i.e. it is abstract or an
|
|
interface), or does not implement ``MongoDB\BSON\Unserializable``, then an
|
|
``MongoDB\Driver\Exception\InvalidArgumentException`` exception is thrown.
|
|
|
|
If the BSON object has a ``__pclass`` property and that class exists and
|
|
implements ``MongoDB\BSON\Persistable``, it will supersede the class provided
|
|
in the type map.
|
|
|
|
The properties of the BSON document, **including** the ``__pclass`` property
|
|
if it exists, will be sent as an associative array to the ``bsonUnserialize``
|
|
function to initialise the object's properties.
|
|
|
|
Scalar Types
|
|
------------
|
|
|
|
For types that the driver has a wrapper class for, it is possible to define a
|
|
map from each supported data type to a class of your own, providing it
|
|
implements the ``MongoDB\BSON\TypeWrapper`` interface.
|
|
|
|
The supported data types are Binary, Decimal128, Javascript, MaxKey, MinKey,
|
|
ObjectId, Regex, Timestamp, and UTCDateTime.
|
|
|
|
The ``MongoDB\BSON\TypeWrapper`` interface defines two functions:
|
|
``createFromBSONType()``, a factory method which takes a ``MongoDB\BSON\Type``
|
|
argument, and ``toBSONType()``.
|
|
|
|
As an example, a wrapped UTCDateTime class, could look like::
|
|
|
|
class UTCDateTimeWrapper implements \MongoDB\BSON\TypeWrapper
|
|
{
|
|
private $intern;
|
|
|
|
public function __construct( \MongoDB\BSON\UTCDateTime $type )
|
|
{
|
|
$this->intern = $type->toDateTime();
|
|
}
|
|
|
|
static function createFromBSONType(\MongoDB\BSON\Type $type)
|
|
{
|
|
if (! $type instanceof \MongoDB\BSON\UTCDateTime) {
|
|
throw new UnexpectedValueException;
|
|
}
|
|
|
|
return new self( $type );
|
|
}
|
|
|
|
function toBSONType()
|
|
{
|
|
return new \MongoDB\BSON\UTCDateTime( $this->intern );
|
|
}
|
|
}
|
|
|
|
|
|
If the defined class wraps (composes) an original ``MongoDB\BSON\*`` class,
|
|
then it SHOULD also implement the accompanying
|
|
``\MongoDB\BSON\<classname>Interface`` interface.
|
|
|
|
The type interfaces include all the type-specific methods from the
|
|
original class, with the exact same arguments and return types. For example,
|
|
they will not include the ``__construct()`` and ``__debugInfo()`` methods.
|
|
|
|
For example, a user-defined ``UTCDateTimeWrapper`` class needs to implement the
|
|
``MongoDB\BSON\UTCDateTimeInterface`` and ``MongoDB\BSON\TypeWrapper``
|
|
interfaces.
|
|
|
|
The ``toBSONType()`` method must return a value that can be serialized to
|
|
BSON, e.g. a scalar value, or an object that implements
|
|
``MongoDB\BSON\Serializable``. If you return an object that implements
|
|
``MongoDB\BSON\TypeWrapper``, the driver will not call the ``toBSONType()``
|
|
method on this new object.
|
|
|
|
Returning a different type from the original one could be used as a way to
|
|
migrate Decimal128 values to plain strings, or downgrade them to floating
|
|
points or integers. Likewise, you could implement a UTCDateTime wrapper that
|
|
converts dates to a formatted string; however, that would prevent
|
|
round-tripping of the original date value.
|
|
|
|
|
|
TypeMaps
|
|
--------
|
|
|
|
TypeMaps can be set through the ``setTypeMap()`` method on a
|
|
``MongoDB\Driver\Cursor`` object, or the ``$typeMap`` argument of
|
|
``MongoDB\BSON\toPHP()`` (previously, ``MongoDB\BSON\toArray()``). Each of the
|
|
three classes (``root``, ``document`` and ``array``) can be individually set.
|
|
|
|
Additionally, you can specify the scalar type mappings through a ``types``
|
|
element. Each element in that ``types`` array maps a MongoDB data type to
|
|
a user-defined class name.
|
|
|
|
If the named class does not exist, is not concrete (i.e. it is abstract or an
|
|
interface), or does not implement ``MongoDB\BSON\TypeWrapper``, then an
|
|
``MongoDB\Driver\Exception\InvalidArgumentException`` exception is thrown.
|
|
|
|
Examples
|
|
--------
|
|
|
|
These examples use the following classes:
|
|
|
|
- ``MyClass``, which does **not** implement any interface
|
|
- ``YourClass``, which implements ``MongoDB\BSON\Unserializable``
|
|
- ``OurClass``, which implements ``MongoDB\BSON\Persistable``
|
|
- ``TheirClass``, which extends ``OurClass``
|
|
|
|
The ``bsonUnserialize()`` method of ``YourClass``, ``OurClass``, ``TheirClass``
|
|
iterate over the array and set the properties without modifications. It
|
|
**also** sets the ``$unserialized`` property to ``true``::
|
|
|
|
function bsonUnserialize( array $map )
|
|
{
|
|
foreach ( $map as $k => $value )
|
|
{
|
|
$this->$k = $value;
|
|
}
|
|
$this->unserialized = true;
|
|
}
|
|
|
|
::
|
|
|
|
/* typemap: [] (all defaults) */
|
|
{ "foo": "yes", "bar" : false }
|
|
-> stdClass { $foo => 'yes', $bar => false }
|
|
|
|
{ "foo": "no", "array" : [ 5, 6 ] }
|
|
-> stdClass { $foo => 'no', $array => [ 5, 6 ] }
|
|
|
|
{ "foo": "no", "obj" : { "embedded" : 3.14 } }
|
|
-> stdClass { $foo => 'no', $obj => stdClass { $embedded => 3.14 } }
|
|
|
|
{ "foo": "yes", "__pclass": "MyClass" }
|
|
-> stdClass { $foo => 'yes', $__pclass => 'MyClass' }
|
|
|
|
{ "foo": "yes", "__pclass": { "$type" : "80", "$binary" : "MyClass" } }
|
|
-> stdClass { $foo => 'yes', $__pclass => Binary(0x80, 'MyClass') }
|
|
|
|
{ "foo": "yes", "__pclass": { "$type" : "80", "$binary" : "YourClass") }
|
|
-> stdClass { $foo => 'yes', $__pclass => Binary(0x80, 'YourClass') }
|
|
|
|
{ "foo": "yes", "__pclass": { "$type" : "80", "$binary" : "OurClass") }
|
|
-> OurClass { $foo => 'yes', $__pclass => Binary(0x80, 'OurClass'), $unserialized => true }
|
|
|
|
{ "foo": "yes", "__pclass": { "$type" : "44", "$binary" : "YourClass") }
|
|
-> stdClass { $foo => 'yes', $__pclass => Binary(0x44, 'YourClass') }
|
|
|
|
::
|
|
|
|
/* typemap: [ "root" => "MissingClass" ] */
|
|
{ "foo": "yes" }
|
|
-> MongoDB\Driver\Exception\InvalidArgumentException("MissingClass does not exist")
|
|
|
|
/* typemap: [ "root" => "MyClass" ] */
|
|
{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "MyClass" } }
|
|
-> MongoDB\Driver\Exception\InvalidArgumentException("MyClass does not implement Unserializable interface")
|
|
|
|
/* typemap: [ "root" => "MongoDB\BSON\Unserializable" ] */
|
|
{ "foo": "yes" }
|
|
-> MongoDB\Driver\Exception\InvalidArgumentException("Unserializable is not a concrete class")
|
|
|
|
/* typemap: [ "root" => "YourClass" ] */
|
|
{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "MongoDB\BSON\Unserializable" } }
|
|
-> YourClass { $foo => "yes", $__pclass => Binary(0x80, "MongoDB\BSON\Unserializable"), $unserialized => true }
|
|
|
|
/* typemap: [ "root" => "YourClass" ] */
|
|
{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "MyClass" } }
|
|
-> YourClass { $foo => "yes", $__pclass => Binary(0x80, "MyClass"), $unserialized => true }
|
|
|
|
/* typemap: [ "root" => "YourClass" ] */
|
|
{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "OurClass" } }
|
|
-> OurClass { $foo => "yes", $__pclass => Binary(0x80, "OurClass"), $unserialized => true }
|
|
|
|
/* typemap: [ "root" => "YourClass" ] */
|
|
{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "TheirClass" } }
|
|
-> TheirClass { $foo => "yes", $__pclass => Binary(0x80, "TheirClass"), $unserialized => true }
|
|
|
|
/* typemap: [ "root" => "OurClass" ] */
|
|
{ foo: "yes", "__pclass" : { "$type": "80", "$binary": "TheirClass" } }
|
|
-> TheirClass { $foo => "yes", $__pclass => Binary(0x80, "TheirClass"), $unserialized => true }
|
|
|
|
::
|
|
|
|
/* typemap: [ 'root' => 'YourClass' ] */
|
|
{ foo: "yes", "__pclass" : { "$type": "80", "$binary": "YourClass" } }
|
|
-> YourClass { $foo => 'yes', $__pclass => Binary(0x80, 'YourClass'), $unserialized => true }
|
|
|
|
::
|
|
|
|
/* typemap: [ 'root' => 'array', 'document' => 'array' ] */
|
|
{ "foo": "yes", "bar" : false }
|
|
-> [ "foo" => "yes", "bar" => false ]
|
|
|
|
{ "foo": "no", "array" : [ 5, 6 ] }
|
|
-> [ "foo" => "no", "array" => [ 5, 6 ] ]
|
|
|
|
{ "foo": "no", "obj" : { "embedded" : 3.14 } }
|
|
-> [ "foo" => "no", "obj" => [ "embedded => 3.14 ] ]
|
|
|
|
{ "foo": "yes", "__pclass": "MyClass" }
|
|
-> [ "foo" => "yes", "__pclass" => "MyClass" ]
|
|
|
|
{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "MyClass" } }
|
|
-> [ "foo" => "yes", "__pclass" => Binary(0x80, "MyClass") ]
|
|
|
|
{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "OurClass" } }
|
|
-> [ "foo" => "yes", "__pclass" => Binary(0x80, "OurClass") ]
|
|
|
|
::
|
|
|
|
/* typemap: [ 'root' => 'object', 'document' => 'object' ] */
|
|
{ "foo": "yes", "__pclass": { "$type": "80", "$binary": "MyClass" } }
|
|
-> stdClass { $foo => "yes", "__pclass" => Binary(0x80, "MyClass") }
|
|
|
|
::
|
|
|
|
/* typemap: [ 'types' => [ 'UTCDateTime' => 'UTCDateTimeWrapper' ] ] */
|
|
{ "date" : ISODate("2016-07-19T16:49:54") }
|
|
-> stdClass { $date => UTCDateTimeWrapper(…) }
|
|
|
|
/* typemap: [ 'types' => [ 'UTCDateTime' => 'UTCDateTimeAsUnixTimestamp' ] ] */
|
|
{ "date" : ISODate("2016-07-19T16:49:54") }
|
|
-> stdClass { $date => 1468946994 }
|
|
|
|
|
|
Related Tickets
|
|
===============
|
|
|
|
- PHPC-248_: Allow ->setTypeMap() to set 'array' and 'stdclass'
|
|
- PHPC-249_: empty array should be serialized as array
|
|
- PHPC-260_: Allow "object" as an alias of "stdClass" for setTypeMap()
|
|
- PHPC-274_: zval_to_bson() ignores BSON\Serializable interface
|
|
- PHPC-275_: object_to_bson() should throw exception if bsonSerialize()
|
|
returns non-array
|
|
- PHPC-288_: ODS (Object Document Serializer) support and integrations
|
|
- PHPC-311_: Rename BSON from/toArray() methods to from/toPHP()
|
|
- PHPC-315_: Support explicit type mapping for top-level documents
|
|
- PHPC-318_: Cursor type map should apply to top-level document
|
|
- PHPC-319_: Top level documents should be deserialized as stdClass by default
|
|
- PHPC-329_: Determine if ODM class should always supersede the type map
|
|
|
|
- HHVM-55_: Implement BSON\Peristable interface
|
|
- HHVM-56_: Implement BSON\Serializable interface
|
|
- HHVM-57_: Implement BSON\Unserializable interface
|
|
- HHVM-63_: Empty array should be serialized as empty array, and empty object
|
|
should be serialized as empty object
|
|
- HHVM-64_: Allow ->setTypeMap() to set 'array' and 'stdclass'
|
|
- HHVM-67_: ODM should only match field of specific name (__pclass)
|
|
- HHVM-84_: Implement MongoDB\BSON\Serializable
|
|
- HHVM-85_: Implement MongoDB\BSON\Unserializable / MongoDB\BSON\Persistable
|
|
- HHVM-214_ Implement interfaces for userland BSON type classes
|
|
|
|
- PHP-1457_: MongoCollection::insert() Non-public properties of objects.
|
|
|
|
|
|
|
|
.. _PHPC-248: https://jira.mongodb.org/browse/PHPC-248
|
|
.. _PHPC-249: https://jira.mongodb.org/browse/PHPC-249
|
|
.. _PHPC-260: https://jira.mongodb.org/browse/PHPC-260
|
|
.. _PHPC-274: https://jira.mongodb.org/browse/PHPC-274
|
|
.. _PHPC-275: https://jira.mongodb.org/browse/PHPC-275
|
|
.. _PHPC-288: https://jira.mongodb.org/browse/PHPC-288
|
|
.. _PHPC-311: https://jira.mongodb.org/browse/PHPC-311
|
|
.. _PHPC-315: https://jira.mongodb.org/browse/PHPC-315
|
|
.. _PHPC-318: https://jira.mongodb.org/browse/PHPC-318
|
|
.. _PHPC-319: https://jira.mongodb.org/browse/PHPC-319
|
|
.. _PHPC-329: https://jira.mongodb.org/browse/PHPC-329
|
|
.. _HHVM-55: https://jira.mongodb.org/browse/HHVM-55
|
|
.. _HHVM-56: https://jira.mongodb.org/browse/HHVM-56
|
|
.. _HHVM-57: https://jira.mongodb.org/browse/HHVM-57
|
|
.. _HHVM-63: https://jira.mongodb.org/browse/HHVM-63
|
|
.. _HHVM-64: https://jira.mongodb.org/browse/HHVM-64
|
|
.. _HHVM-67: https://jira.mongodb.org/browse/HHVM-67
|
|
.. _HHVM-84: https://jira.mongodb.org/browse/HHVM-84
|
|
.. _HHVM-85: https://jira.mongodb.org/browse/HHVM-85
|
|
.. _HHVM-214: https://jira.mongodb.org/browse/HHVM-214
|
|
.. _PHP-1457: https://jira.mongodb.org/browse/PHP-1457
|
|
|
|
Unrelated Tickets
|
|
=================
|
|
|
|
- PHPC-314_: Prototype type map syntax for documents within field paths
|
|
|
|
.. _PHPC-314: https://jira.mongodb.org/browse/PHPC-314
|
|
|
|
.. [1] A ``__pclass`` property is only deemed to exist if there exists a
|
|
property with that name, **and** it is a Binary value, **and** the
|
|
sub-type of the Binary value is ``0x80``. If any of these three conditions
|
|
is not met, the ``__pclass`` property does not exist and should be treated
|
|
as any other normal property.
|