You are browsing a version that has not yet been released.

Embedded Mapping

This chapter explains how embedded documents are mapped in Doctrine.

Embed One

Embed a single document:

  • PHP
    1<?php /** @Document */ class User { // ... /** @EmbedOne(targetDocument=Address::class) */ private $address; // ... } /** @EmbeddedDocument */ class Address { /** @Field(type="string") */ private $street; // ... }
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
  • XML
    1<?xml version="1.0" encoding="UTF-8"?> <doctrine-mongo-mapping xmlns="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd"> <document name="Documents\User"> <embed-one field="address" target-document="Address" /> </document> <embedded-document name="Address"> <field name="street" type="string" /> </embedded-document> </doctrine-mongo-mapping>
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

Embed Many

Embed many documents:

  • PHP
    1<?php use Doctrine\Common\Collections\ArrayCollection; /** @Document */ class User { // ... /** @EmbedMany(targetDocument=Phonenumber::class) */ private $phoneNumbers; // ... public function __construct() { $this->phoneNumbers = new ArrayCollection(); } } /** @EmbeddedDocument */ class PhoneNumber { /** @Field(type="string") */ private $number; // ... }
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
  • XML
    1<?xml version="1.0" encoding="UTF-8"?> <doctrine-mongo-mapping xmlns="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd"> <document name="Documents\User"> <embed-many field="phoneNumbers" target-document="PhoneNumber" /> </document> <embedded-document name="PhoneNumber"> <field name="number" type="string" /> </embedded-document> </doctrine-mongo-mapping>
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

Mixing Document Types

If you want to store different types of embedded documents in the same field, you can simply omit the targetDocument option:

  • PHP
    1<?php use Doctrine\Common\Collections\ArrayCollection; /** @Document */ class User { // .. /** @EmbedMany */ private $tasks; // ... public function __construct() { $this->tasks = new ArrayCollection(); } }
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
  • XML
    1<embed-many field="tasks" />

Now the $tasks property can store any type of document! The class name will be automatically stored in a field named _doctrine_class_name within the embedded document. The field name can be customized with the discriminatorField option:

  • PHP
    1<?php use Doctrine\Common\Collections\ArrayCollection; /** @Document */ class User { // .. /** * @EmbedMany(discriminatorField="type") */ private $tasks; // ... public function __construct() { $this->tasks = new ArrayCollection(); } }
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
  • XML
    1<embed-many field="tasks"> <discriminator-field name="type" /> </embed-many>
    2
    3

You can also specify a discriminator map to avoid storing the FQCN in each embedded document:

  • PHP
    1<?php use Doctrine\Common\Collections\ArrayCollection; /** @Document */ class User { // .. /** * @EmbedMany( * discriminatorMap={ * "download"=DownloadTask::class, * "build"=BuildTask::class * } * ) */ private $tasks; // ... public function __construct() { $this->tasks = new ArrayCollection(); } }
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
  • XML
    1<embed-many field="tasks"> <discriminator-map> <discriminator-mapping value="download" class="DownloadTask" /> <discriminator-mapping value="build" class="BuildTask" /> </discriminator-map> </embed-many>
    2
    3
    4
    5
    6

If you have embedded documents without a discriminator value that need to be treated correctly you can optionally specify a default value for the discriminator:

  • PHP
    1<?php /** @Document */ class User { // .. /** * @EmbedMany( * discriminatorMap={ * "download"=DownloadTask::class, * "build"=BuildTask::class * }, * defaultDiscriminatorValue="download" * ) */ private $tasks = []; // ... }
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
  • XML
    1<embed-many field="tasks"> <discriminator-map> <discriminator-mapping value="download" class="DownloadTask" /> <discriminator-mapping value="build" class="BuildTask" /> </discriminator-map> <default-discriminator-value value="download" /> </embed-many>
    2
    3
    4
    5
    6
    7

Cascading Operations

All operations on embedded documents are automatically cascaded. This is because embedded documents are part of their parent document and cannot exist without those by nature.

Storing Empty Arrays in Embedded Documents

By default, when an embedded collection property is empty, Doctrine does not store any data for it in the database. However, in some cases, you may want to explicitly store an empty array for such properties. You can achieve this behavior by using the `storeEmptyArray` option for embedded collections.

  • PHP
    1<?php /** @Document */ class User { // ... /** * @EmbedMany(targetDocument=PhoneNumber::class, storeEmptyArray=true) */ private $phoneNumbers = []; // ... }
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
  • XML
    1<?xml version="1.0" encoding="UTF-8"?> <doctrine-mongo-mapping xmlns="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd"> <document name="Documents\User"> <embed-many field="phoneNumbers" target-document="PhoneNumber" store-empty-array="true" /> </document> <embedded-document name="PhoneNumber"> <field name="number" type="string" /> </embedded-document> </doctrine-mongo-mapping>
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

Now, when the `$phoneNumbers` collection is empty, an empty array will be stored in the database for the `User` document's embedded `phoneNumbers` collection, even if there are no actual embedded documents in the collection.