You are browsing a version that is no longer maintained.

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.