mongodb-odm-docs-dash/Doctrine ODM.docset/Contents/Resources/Documents/reference/reference-mapping.html

625 lines
38 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Reference Mapping &mdash; Doctrine MongoDB ODM 1.1.5 documentation</title>
<link rel="stylesheet" href="../_static/bootstrap/css/bootstrap.min.css" type="text/css" />
<link rel="stylesheet" href="../_static/default.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="../_static/layout.css" type="text/css" />
<link rel="stylesheet" href="../_static/configurationblock.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: '../',
VERSION: '1.1.5',
COLLAPSE_MODINDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true
};
</script>
<script type="text/javascript" src="../_static/jquery.js"></script>
<script type="text/javascript" src="../_static/configurationblock.js"></script>
<script type="text/javascript" src="../_static/underscore.js"></script>
<script type="text/javascript" src="../_static/configurationblock.js"></script>
<script type="text/javascript" src="../_static/doctools.js"></script>
<script type="text/javascript" src="../_static/configurationblock.js"></script>
<script src="../_static/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript">
<!--
$(document).ready(function() {
$("#versions").change(function() {
var docsUrl = $(this).val();
window.location.href = docsUrl;
});
});
-->
</script>
<link rel="shortcut icon" href="../_static/doctrine.ico"/>
<link rel="search" title="Search" href="../search.html" />
<link rel="top" title="Doctrine MongoDB ODM 1.1.5 documentation" href="../index.html" />
</head>
<body>
<div id="wrapper">
<div id="header">
<h1 id="h1title"></h1>
<div id="logo">
<a href="http://www.doctrine-project.org/">Doctrine - PHP Database Libraries</a>
</div>
</div>
<div id="nav" class="cls">
<div class="tl cls">
<ul>
<li><a target="_top" href="http://www.doctrine-project.org/">Home</a></li>
<li><a target="_top" href="http://www.doctrine-project.org/about.html">About</a></li>
<li><a target="_top" href="http://www.doctrine-project.org/projects.html">Projects</a></li>
<li><a target="_top" href="http://www.doctrine-project.org/contribute.html">Contribute</a></li>
<li><a target="_top" href="http://www.doctrine-project.org/community.html">Community</a></li>
<li><a target="_top" href="http://www.doctrine-project.org/archive.html">Blog</a></li>
<li><a target="_top" href="http://www.doctrine-project.org/jira">Development</a></li>
</ul>
</div>
</div>
<div id="content" class="cls">
<div class="related">
<h3>Navigation</h3>
<ul>
<li><a href="/">Doctrine Homepage</a> &raquo;</li>
<li><a href="../index.html">Doctrine MongoDB ODM 1.1.5 documentation</a> &raquo;</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" >
<div class="section" id="reference-mapping">
<h1>Reference Mapping<a class="headerlink" href="#reference-mapping" title="Permalink to this headline"></a></h1>
<p>This chapter explains how references between documents are mapped with Doctrine.</p>
<div class="section" id="collections">
<h2>Collections<a class="headerlink" href="#collections" title="Permalink to this headline"></a></h2>
<p>Examples of many-valued references in this manual make use of a <code class="docutils literal"><span class="pre">Collection</span></code>
interface and a corresponding <code class="docutils literal"><span class="pre">ArrayCollection</span></code> implementation, which are
defined in the <code class="docutils literal"><span class="pre">Doctrine\Common\Collections</span></code> namespace. These classes have no
dependencies on ODM, and can therefore be used within your domain model and
elsewhere without introducing coupling to the persistence layer.</p>
<p>ODM also provides a <code class="docutils literal"><span class="pre">PersistentCollection</span></code> implementation of <code class="docutils literal"><span class="pre">Collection</span></code>,
which incorporates change-tracking functionality; however, this class is
constructed internally during hydration. As a developer, you should develop with
the <code class="docutils literal"><span class="pre">Collection</span></code> interface in mind so that your code can operate with any
implementation.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">New in 1.1: you are no longer limited to using <code class="docutils literal"><span class="pre">ArrayCollection</span></code> and can
freely use your own <code class="docutils literal"><span class="pre">Collection</span></code> implementation. For more details please
see <a class="reference internal" href="custom-collections.html"><span class="doc">Custom Collections</span></a> chapter.</p>
</div>
<p>Why are these classes used over PHP arrays? Native arrays cannot be
transparently extended in PHP, which is necessary for many advanced features
provided by the ODM. Although PHP does provide various interfaces that allow
objects to operate like arrays (e.g. <code class="docutils literal"><span class="pre">Traversable</span></code>, <code class="docutils literal"><span class="pre">Countable</span></code>,
<code class="docutils literal"><span class="pre">ArrayAccess</span></code>), and even a concrete implementation in <code class="docutils literal"><span class="pre">ArrayObject</span></code>, these
objects cannot always be used everywhere that a native array is accepted.
Doctrine's <code class="docutils literal"><span class="pre">Collection</span></code> interface and <code class="docutils literal"><span class="pre">ArrayCollection</span></code> implementation are
conceptually very similar to <code class="docutils literal"><span class="pre">ArrayObject</span></code>, with some slight differences and
improvements.</p>
</div>
<div class="section" id="reference-one">
<span id="id1"></span><h2>Reference One<a class="headerlink" href="#reference-one" title="Permalink to this headline"></a></h2>
<p>Reference one document:</p>
<div class="configuration-block">
<ul class="simple">
<li><em>PHP</em><div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/** @Document */</span>
<span class="k">class</span> <span class="nc">Product</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="sd">/**</span>
<span class="sd"> * @ReferenceOne(targetDocument=&quot;Shipping&quot;)</span>
<span class="sd"> */</span>
<span class="k">private</span> <span class="nv">$shipping</span><span class="p">;</span>
<span class="c1">// ...</span>
<span class="p">}</span>
<span class="sd">/** @Document */</span>
<span class="k">class</span> <span class="nc">Shipping</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</div>
</li>
<li><em>XML</em><div class="highlight-xml"><div class="highlight"><pre><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span>
<span class="nt">&lt;doctrine-mongo-mapping</span> <span class="na">xmlns=</span><span class="s">&quot;http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping&quot;</span>
<span class="na">xmlns:xsi=</span><span class="s">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span>
<span class="na">xsi:schemaLocation=</span><span class="s">&quot;http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping</span>
<span class="s"> http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;document</span> <span class="na">name=</span><span class="s">&quot;Documents\Product&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;reference-one</span> <span class="na">field=</span><span class="s">&quot;shipping&quot;</span> <span class="na">target-document=</span><span class="s">&quot;Documents\Shipping&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/document&gt;</span>
<span class="nt">&lt;/doctrine-mongo-mapping&gt;</span>
</pre></div>
</div>
</li>
<li><em>YAML</em><div class="highlight-yaml"><div class="highlight"><pre><span class="l l-Scalar l-Scalar-Plain">Product</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">type</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">document</span>
<span class="l l-Scalar l-Scalar-Plain">referenceOne</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">shipping</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">targetDocument</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">Documents\Shipping</span>
</pre></div>
</div>
</li>
</ul>
</div>
</div>
<div class="section" id="reference-many">
<span id="id2"></span><h2>Reference Many<a class="headerlink" href="#reference-many" title="Permalink to this headline"></a></h2>
<p>Reference many documents:</p>
<div class="configuration-block">
<ul class="simple">
<li><em>PHP</em><div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/** @Document */</span>
<span class="k">class</span> <span class="nc">User</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="sd">/**</span>
<span class="sd"> * @ReferenceMany(targetDocument=&quot;Account&quot;)</span>
<span class="sd"> */</span>
<span class="k">private</span> <span class="nv">$accounts</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span>
<span class="c1">// ...</span>
<span class="p">}</span>
<span class="sd">/** @Document */</span>
<span class="k">class</span> <span class="nc">Account</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</div>
</li>
<li><em>XML</em><div class="highlight-xml"><div class="highlight"><pre><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span>
<span class="nt">&lt;doctrine-mongo-mapping</span> <span class="na">xmlns=</span><span class="s">&quot;http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping&quot;</span>
<span class="na">xmlns:xsi=</span><span class="s">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span>
<span class="na">xsi:schemaLocation=</span><span class="s">&quot;http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping</span>
<span class="s"> http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;document</span> <span class="na">name=</span><span class="s">&quot;Documents\Product&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;reference-many</span> <span class="na">field=</span><span class="s">&quot;accounts&quot;</span> <span class="na">target-document=</span><span class="s">&quot;Documents\Account&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/document&gt;</span>
<span class="nt">&lt;/doctrine-mongo-mapping&gt;</span>
</pre></div>
</div>
</li>
<li><em>YAML</em><div class="highlight-yaml"><div class="highlight"><pre><span class="l l-Scalar l-Scalar-Plain">User</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">type</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">document</span>
<span class="l l-Scalar l-Scalar-Plain">referenceMany</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">accounts</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">targetDocument</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">Documents\Account</span>
</pre></div>
</div>
</li>
</ul>
</div>
</div>
<div class="section" id="mixing-document-types">
<span id="reference-mixing-document-types"></span><h2>Mixing Document Types<a class="headerlink" href="#mixing-document-types" title="Permalink to this headline"></a></h2>
<p>If you want to store different types of documents in references, you can simply
omit the <code class="docutils literal"><span class="pre">targetDocument</span></code> option:</p>
<div class="configuration-block">
<ul class="simple">
<li><em>PHP</em><div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/** @Document */</span>
<span class="k">class</span> <span class="nc">User</span>
<span class="p">{</span>
<span class="c1">// ..</span>
<span class="sd">/** @ReferenceMany */</span>
<span class="k">private</span> <span class="nv">$favorites</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span>
<span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</div>
</li>
<li><em>XML</em><div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;field</span> <span class="na">fieldName=</span><span class="s">&quot;favorites&quot;</span> <span class="nt">/&gt;</span>
</pre></div>
</div>
</li>
<li><em>YAML</em><div class="highlight-yaml"><div class="highlight"><pre><span class="l l-Scalar l-Scalar-Plain">referenceMany</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">favorites</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">~</span>
</pre></div>
</div>
</li>
</ul>
</div>
<p>Now the <code class="docutils literal"><span class="pre">$favorites</span></code> property can store a reference to any type of document!
The class name will be automatically stored in a field named
<code class="docutils literal"><span class="pre">_doctrine_class_name</span></code> within the <a class="reference external" href="https://docs.mongodb.com/manual/reference/database-references/#dbrefs">DBRef</a> object.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">The MongoDB shell tends to ignore fields other than <code class="docutils literal"><span class="pre">$id</span></code> and <code class="docutils literal"><span class="pre">$ref</span></code>
when displaying <a class="reference external" href="https://docs.mongodb.com/manual/reference/database-references/#dbrefs">DBRef</a> objects. You can verify the presence of any <code class="docutils literal"><span class="pre">$db</span></code>
and discriminator fields by querying and examining the document with a
driver. See <a class="reference external" href="https://jira.mongodb.org/browse/SERVER-10777">SERVER-10777</a>
for additional discussion on this issue.</p>
</div>
<p>The name of the field within the DBRef object can be customized via the
<code class="docutils literal"><span class="pre">discriminatorField</span></code> option:</p>
<div class="configuration-block">
<ul class="simple">
<li><em>PHP</em><div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/** @Document */</span>
<span class="k">class</span> <span class="nc">User</span>
<span class="p">{</span>
<span class="c1">// ..</span>
<span class="sd">/**</span>
<span class="sd"> * @ReferenceMany(discriminatorField=&quot;type&quot;)</span>
<span class="sd"> */</span>
<span class="k">private</span> <span class="nv">$favorites</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span>
<span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</div>
</li>
<li><em>XML</em><div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;reference-many</span> <span class="na">fieldName=</span><span class="s">&quot;favorites&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;discriminator-field</span> <span class="na">name=</span><span class="s">&quot;type&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/reference-many&gt;</span>
</pre></div>
</div>
</li>
<li><em>YAML</em><div class="highlight-yaml"><div class="highlight"><pre><span class="l l-Scalar l-Scalar-Plain">referenceMany</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">favorites</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">discriminatorField</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">type</span>
</pre></div>
</div>
</li>
</ul>
</div>
<p>You can also specify a discriminator map to avoid storing the <a href="#id4"><span class="problematic" id="id5">|FQCN|</span></a>
in each <a class="reference external" href="https://docs.mongodb.com/manual/reference/database-references/#dbrefs">DBRef</a> object:</p>
<div class="configuration-block">
<ul class="simple">
<li><em>PHP</em><div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/** @Document */</span>
<span class="k">class</span> <span class="nc">User</span>
<span class="p">{</span>
<span class="c1">// ..</span>
<span class="sd">/**</span>
<span class="sd"> * @ReferenceMany(</span>
<span class="sd"> * discriminatorMap={</span>
<span class="sd"> * &quot;album&quot;=&quot;Album&quot;,</span>
<span class="sd"> * &quot;song&quot;=&quot;Song&quot;</span>
<span class="sd"> * }</span>
<span class="sd"> * )</span>
<span class="sd"> */</span>
<span class="k">private</span> <span class="nv">$favorites</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span>
<span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</div>
</li>
<li><em>XML</em><div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;reference-many</span> <span class="na">fieldName=</span><span class="s">&quot;favorites&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;discriminator-map&gt;</span>
<span class="nt">&lt;discriminator-mapping</span> <span class="na">value=</span><span class="s">&quot;album&quot;</span> <span class="na">class=</span><span class="s">&quot;Documents\Album&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;discriminator-mapping</span> <span class="na">value=</span><span class="s">&quot;song&quot;</span> <span class="na">class=</span><span class="s">&quot;Documents\Song&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/discriminator-map&gt;</span>
<span class="nt">&lt;/reference-many&gt;</span>
</pre></div>
</div>
</li>
<li><em>YAML</em><div class="highlight-yaml"><div class="highlight"><pre><span class="l l-Scalar l-Scalar-Plain">referenceMany</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">favorites</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">discriminatorMap</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">album</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">Documents\Album</span>
<span class="l l-Scalar l-Scalar-Plain">song</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">Documents\Song</span>
</pre></div>
</div>
</li>
</ul>
</div>
<p>If you have references without a discriminator value that should be considered
a certain class, you can optionally specify a default discriminator value:</p>
<div class="configuration-block">
<ul class="simple">
<li><em>PHP</em><div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/** @Document */</span>
<span class="k">class</span> <span class="nc">User</span>
<span class="p">{</span>
<span class="c1">// ..</span>
<span class="sd">/**</span>
<span class="sd"> * @ReferenceMany(</span>
<span class="sd"> * discriminatorMap={</span>
<span class="sd"> * &quot;album&quot;=&quot;Album&quot;,</span>
<span class="sd"> * &quot;song&quot;=&quot;Song&quot;</span>
<span class="sd"> * },</span>
<span class="sd"> * defaultDiscriminatorValue=&quot;album&quot;</span>
<span class="sd"> * )</span>
<span class="sd"> */</span>
<span class="k">private</span> <span class="nv">$favorites</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span>
<span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</div>
</li>
<li><em>XML</em><div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;reference-many</span> <span class="na">fieldName=</span><span class="s">&quot;favorites&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;discriminator-map&gt;</span>
<span class="nt">&lt;discriminator-mapping</span> <span class="na">value=</span><span class="s">&quot;album&quot;</span> <span class="na">class=</span><span class="s">&quot;Documents\Album&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;discriminator-mapping</span> <span class="na">value=</span><span class="s">&quot;song&quot;</span> <span class="na">class=</span><span class="s">&quot;Documents\Song&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/discriminator-map&gt;</span>
<span class="nt">&lt;default-discriminator-value</span> <span class="na">value=</span><span class="s">&quot;album&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/reference-many&gt;</span>
</pre></div>
</div>
</li>
<li><em>YAML</em><div class="highlight-yaml"><div class="highlight"><pre><span class="l l-Scalar l-Scalar-Plain">referenceMany</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">favorites</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">discriminatorMap</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">album</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">Documents\Album</span>
<span class="l l-Scalar l-Scalar-Plain">song</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">Documents\Song</span>
<span class="l l-Scalar l-Scalar-Plain">defaultDiscriminatorValue</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">album</span>
</pre></div>
</div>
</li>
</ul>
</div>
</div>
<div class="section" id="storing-references">
<span id="id3"></span><h2>Storing References<a class="headerlink" href="#storing-references" title="Permalink to this headline"></a></h2>
<p>By default all references are stored as a <a class="reference external" href="https://docs.mongodb.com/manual/reference/database-references/#dbrefs">DBRef</a> object with the traditional
<code class="docutils literal"><span class="pre">$ref</span></code>, <code class="docutils literal"><span class="pre">$id</span></code>, and (optionally) <code class="docutils literal"><span class="pre">$db</span></code> fields (in that order). For references to
documents of a single collection, storing the collection (and database) names for
each reference may be redundant. You can use simple references to store the
referenced document's identifier (e.g. <code class="docutils literal"><span class="pre">MongoId</span></code>) instead of a <a class="reference external" href="https://docs.mongodb.com/manual/reference/database-references/#dbrefs">DBRef</a>.</p>
<p>Example:</p>
<div class="configuration-block">
<ul class="simple">
<li><em>PHP</em><div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/**</span>
<span class="sd"> * @ReferenceOne(targetDocument=&quot;Profile&quot;, storeAs=&quot;id&quot;)</span>
<span class="sd"> */</span>
<span class="k">private</span> <span class="nv">$profile</span><span class="p">;</span>
</pre></div>
</div>
</li>
<li><em>XML</em><div class="highlight-xml"><div class="highlight"><pre>&lt;reference-one target-document=&quot;Documents\Profile&quot;, store-as=&quot;id&quot; /&gt;
</pre></div>
</div>
</li>
<li><em>YAML</em><div class="highlight-yaml"><div class="highlight"><pre><span class="l l-Scalar l-Scalar-Plain">referenceOne</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">profile</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">storeAs</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">id</span>
</pre></div>
</div>
</li>
</ul>
</div>
<p>Now, the <code class="docutils literal"><span class="pre">profile</span></code> field will only store the <code class="docutils literal"><span class="pre">MongoId</span></code> of the referenced
Profile document.</p>
<p>Simple references reduce the amount of storage used, both for the document
itself and any indexes on the reference field; however, simple references cannot
be used with discriminators, since there is no <a class="reference external" href="https://docs.mongodb.com/manual/reference/database-references/#dbrefs">DBRef</a> object in which to store
a discriminator value.</p>
<p>In addition to saving references as <a class="reference external" href="https://docs.mongodb.com/manual/reference/database-references/#dbrefs">DBRef</a> with <code class="docutils literal"><span class="pre">$ref</span></code>, <code class="docutils literal"><span class="pre">$id</span></code>, and <code class="docutils literal"><span class="pre">$db</span></code>
fields and as <code class="docutils literal"><span class="pre">MongoId</span></code>, it is possible to save references as <a class="reference external" href="https://docs.mongodb.com/manual/reference/database-references/#dbrefs">DBRef</a> without
the <code class="docutils literal"><span class="pre">$db</span></code> field. This solves problems when the database name changes (and also
reduces the amount of storage used).</p>
<p>The <code class="docutils literal"><span class="pre">storeAs</span></code> option has the following possible values:</p>
<ul class="simple">
<li><strong>dbRefWithDb</strong>: Uses a <a class="reference external" href="https://docs.mongodb.com/manual/reference/database-references/#dbrefs">DBRef</a> with <code class="docutils literal"><span class="pre">$ref</span></code>, <code class="docutils literal"><span class="pre">$id</span></code>, and <code class="docutils literal"><span class="pre">$db</span></code> fields (this is the default)</li>
<li><strong>dbRef</strong>: Uses a <a class="reference external" href="https://docs.mongodb.com/manual/reference/database-references/#dbrefs">DBRef</a> with <code class="docutils literal"><span class="pre">$ref</span></code> and <code class="docutils literal"><span class="pre">$id</span></code></li>
<li><strong>ref</strong>: Uses a custom embedded object with an <code class="docutils literal"><span class="pre">id</span></code> field</li>
<li><strong>id</strong>: Uses the identifier of the referenced object</li>
</ul>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">The <code class="docutils literal"><span class="pre">storeAs=id</span></code> option used to be called a &quot;simple reference&quot;. The old syntax is
still recognized (so using <code class="docutils literal"><span class="pre">simple=true</span></code> will imply <code class="docutils literal"><span class="pre">storeAs=id</span></code>).</p>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">For backwards compatibility <code class="docutils literal"><span class="pre">storeAs=dbRefWithDb</span></code> is the default, but
<code class="docutils literal"><span class="pre">storeAs=ref</span></code> is the recommended setting.</p>
</div>
</div>
<div class="section" id="cascading-operations">
<h2>Cascading Operations<a class="headerlink" href="#cascading-operations" title="Permalink to this headline"></a></h2>
<p>By default, Doctrine will not cascade any <code class="docutils literal"><span class="pre">UnitOfWork</span></code> operations to
referenced documents. You must explicitly enable this functionality:</p>
<div class="configuration-block">
<ul class="simple">
<li><em>PHP</em><div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/**</span>
<span class="sd"> * @ReferenceOne(targetDocument=&quot;Profile&quot;, cascade={&quot;persist&quot;})</span>
<span class="sd"> */</span>
<span class="k">private</span> <span class="nv">$profile</span><span class="p">;</span>
</pre></div>
</div>
</li>
<li><em>XML</em><div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;reference-one</span> <span class="na">target-document=</span><span class="s">&quot;Documents\Profile&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;cascade&gt;</span>
<span class="nt">&lt;persist/&gt;</span>
<span class="nt">&lt;/cascade&gt;</span>
<span class="nt">&lt;/reference-one&gt;</span>
</pre></div>
</div>
</li>
<li><em>YAML</em><div class="highlight-yaml"><div class="highlight"><pre><span class="l l-Scalar l-Scalar-Plain">referenceOne</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">profile</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">cascade</span><span class="p p-Indicator">:</span> <span class="p p-Indicator">[</span><span class="nv">persist</span><span class="p p-Indicator">]</span>
</pre></div>
</div>
</li>
</ul>
</div>
<p>The valid values are:</p>
<ul class="simple">
<li><strong>all</strong> - cascade all operations by default.</li>
<li><strong>detach</strong> - cascade detach operation to referenced documents.</li>
<li><strong>merge</strong> - cascade merge operation to referenced documents.</li>
<li><strong>refresh</strong> - cascade refresh operation to referenced documents.</li>
<li><strong>remove</strong> - cascade remove operation to referenced documents.</li>
<li><strong>persist</strong> - cascade persist operation to referenced documents.</li>
</ul>
</div>
<div class="section" id="orphan-removal">
<h2>Orphan Removal<a class="headerlink" href="#orphan-removal" title="Permalink to this headline"></a></h2>
<p>There is another concept of cascading that is relevant only when removing documents
from collections. If a Document of type <code class="docutils literal"><span class="pre">A</span></code> contains references to privately
owned Documents <code class="docutils literal"><span class="pre">B</span></code> then if the reference from <code class="docutils literal"><span class="pre">A</span></code> to <code class="docutils literal"><span class="pre">B</span></code> is removed the
document <code class="docutils literal"><span class="pre">B</span></code> should also be removed, because it is not used anymore.</p>
<p>OrphanRemoval works with both reference one and many mapped fields.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">When using the <code class="docutils literal"><span class="pre">orphanRemoval=true</span></code> option Doctrine makes the assumption
that the documents are privately owned and will <strong>NOT</strong> be reused by other documents.
If you neglect this assumption your documents will get deleted by Doctrine even if
you assigned the orphaned documents to another one.</p>
</div>
<p>As a better example consider an Addressbook application where you have Contacts, Addresses
and StandingData:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">namespace</span> <span class="nx">Addressbook</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Doctrine\Common\Collections\ArrayCollection</span><span class="p">;</span>
<span class="sd">/**</span>
<span class="sd"> * @Document</span>
<span class="sd"> */</span>
<span class="k">class</span> <span class="nc">Contact</span>
<span class="p">{</span>
<span class="sd">/** @Id */</span>
<span class="k">private</span> <span class="nv">$id</span><span class="p">;</span>
<span class="sd">/** @ReferenceOne(targetDocument=&quot;StandingData&quot;, orphanRemoval=true) */</span>
<span class="k">private</span> <span class="nv">$standingData</span><span class="p">;</span>
<span class="sd">/** @ReferenceMany(targetDocument=&quot;Address&quot;, mappedBy=&quot;contact&quot;, orphanRemoval=true) */</span>
<span class="k">private</span> <span class="nv">$addresses</span><span class="p">;</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">__construct</span><span class="p">()</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">addresses</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ArrayCollection</span><span class="p">();</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">newStandingData</span><span class="p">(</span><span class="nx">StandingData</span> <span class="nv">$sd</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">standingData</span> <span class="o">=</span> <span class="nv">$sd</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">removeAddress</span><span class="p">(</span><span class="nv">$pos</span><span class="p">)</span>
<span class="p">{</span>
<span class="nb">unset</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">addresses</span><span class="p">[</span><span class="nv">$pos</span><span class="p">]);</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Now two examples of what happens when you remove the references:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$contact</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">find</span><span class="p">(</span><span class="s2">&quot;Addressbook\Contact&quot;</span><span class="p">,</span> <span class="nv">$contactId</span><span class="p">);</span>
<span class="nv">$contact</span><span class="o">-&gt;</span><span class="na">newStandingData</span><span class="p">(</span><span class="k">new</span> <span class="nx">StandingData</span><span class="p">(</span><span class="s2">&quot;Firstname&quot;</span><span class="p">,</span> <span class="s2">&quot;Lastname&quot;</span><span class="p">,</span> <span class="s2">&quot;Street&quot;</span><span class="p">));</span>
<span class="nv">$contact</span><span class="o">-&gt;</span><span class="na">removeAddress</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">flush</span><span class="p">();</span>
</pre></div>
</div>
<p>In this case you have not only changed the <code class="docutils literal"><span class="pre">Contact</span></code> document itself but
you have also removed the references for standing data and as well as one
address reference. When flush is called not only are the references removed
but both the old standing data and the one address documents are also deleted
from the database.</p>
</div>
</div>
</div>
</div>
</div>
<div class="sphinxsidebar">
<div class="sphinxsidebarwrapper">
<div id="searchbox" style="">
<h3>Search</h3>
<form class="search" action="http://readthedocs.org/search/project/" method="get">
<input type="text" name="q" size="18">
<input type="submit" value="Go">
<input type="hidden" name="selected_facets" value="project:">
</form>
</div>
<h3><a href="../index.html">Table Of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Reference Mapping</a><ul>
<li><a class="reference internal" href="#collections">Collections</a></li>
<li><a class="reference internal" href="#reference-one">Reference One</a></li>
<li><a class="reference internal" href="#reference-many">Reference Many</a></li>
<li><a class="reference internal" href="#mixing-document-types">Mixing Document Types</a></li>
<li><a class="reference internal" href="#storing-references">Storing References</a></li>
<li><a class="reference internal" href="#cascading-operations">Cascading Operations</a></li>
<li><a class="reference internal" href="#orphan-removal">Orphan Removal</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/reference-mapping.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy; Copyright 2013, Doctrine Project Team.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.6.2.
<br/>
<a target="_BLANK" href="http://www.servergrove.com"><img src="http://www.doctrine-project.org/_static/servergrove.jpg" /></a> <br/><br/>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_s-xclick" />
<input type="hidden" name="hosted_button_id" value="BAE2E3XANQ77Y" />
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!" />
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" />
</form>
</div>
</div>
<div id="bot-rcnr">
<div class="tl"><!-- corner --></div>
</div>
</div>
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-288343-7";
urchinTracker();
</script>
<a class="githublink" href="http://github.com/doctrine"><img src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png" alt="Fork me on GitHub"></a>
</body>
</html>