This chapter explains how embedded documents are mapped in Doctrine.
Embed a single document:
<?php
/** @Document */
class User
{
// ...
/** @EmbedOne(targetDocument="Address") */
private $address;
// ...
}
/** @EmbeddedDocument */
class Address
{
// ...
}
<?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>
</doctrine-mongo-mapping>
User:
type: document
embedOne:
address:
targetDocument: Address
Address:
type: embeddedDocument
Embed many documents:
<?php
/** @Document */
class User
{
// ...
/** @EmbedMany(targetDocument="Phonenumber") */
private $phonenumbers = array();
// ...
}
/** @EmbeddedDocument */
class Phonenumber
{
// ...
}
<?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>
</doctrine-mongo-mapping>
User:
type: document
embedMany:
phonenumbers:
targetDocument: Phonenumber
Phonenumber:
type: embeddedDocument
If you want to store different types of embedded documents in the same field, you can simply omit the targetDocument
option:
<?php
/** @Document */
class User
{
// ..
/** @EmbedMany */
private $tasks = array();
// ...
}
<embed-many field="tasks" />
embedMany:
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
/** @Document */
class User
{
// ..
/**
* @EmbedMany(discriminatorField="type")
*/
private $tasks = array();
// ...
}
<embed-many fieldName="tasks">
<discriminator-field name="type" />
</embed-many>
embedMany:
tasks:
discriminatorField: type
You can also specify a discriminator map to avoid storing the fully qualified class name in each embedded document:
<?php
/** @Document */
class User
{
// ..
/**
* @EmbedMany(
* discriminatorMap={
* "download"="DownloadTask",
* "build"="BuildTask"
* }
* )
*/
private $tasks = array();
// ...
}
<embed-many fieldName="tasks">
<discriminator-map>
<discriminator-mapping value="download" class="DownloadTask" />
<discriminator-mapping value="build" class="BuildTask" />
</discriminator-map>
</embed-many>
embedMany:
tasks:
discriminatorMap:
download: DownloadTask
build: BuildTask
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.