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
/** @Document */
class User
{
// ...
/** @EmbedOne(targetDocument=Address::class) */
private $address;
// ...
}
/** @EmbeddedDocument */
class Address
{
/** @Field(type="string") */
private $street;
// ...
}
Embed Many
Embed many documents:
<?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;
// ...
}
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
use Doctrine\Common\Collections\ArrayCollection;
/** @Document */
class User
{
// ..
/** @EmbedMany */
private $tasks;
// ...
public function __construct()
{
$this->tasks = new ArrayCollection();
}
}
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
use Doctrine\Common\Collections\ArrayCollection;
/** @Document */
class User
{
// ..
/**
* @EmbedMany(discriminatorField="type")
*/
private $tasks;
// ...
public function __construct()
{
$this->tasks = new ArrayCollection();
}
}
You can also specify a discriminator map to avoid storing the FQCN in each embedded document:
<?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();
}
}
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
/** @Document */
class User
{
// ..
/**
* @EmbedMany(
* discriminatorMap={
* "download"=DownloadTask::class,
* "build"=BuildTask::class
* },
* defaultDiscriminatorValue="download"
* )
*/
private $tasks = [];
// ...
}
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.