Trying a new generation script

This commit is contained in:
2017-12-01 20:06:23 -08:00
parent 59abc53bec
commit 4d1b823198
202 changed files with 5 additions and 5 deletions
@@ -0,0 +1,912 @@
<!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>Aggregation builder &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="aggregation-builder">
<h1>Aggregation builder<a class="headerlink" href="#aggregation-builder" title="Permalink to this headline"></a></h1>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">This feature is introduced in version 1.2</p>
</div>
<p>The aggregation framework provides an easy way to process records and return
computed results. The aggregation builder helps to build complex aggregation
pipelines.</p>
<div class="section" id="creating-an-aggregation-builder">
<h2>Creating an Aggregation Builder<a class="headerlink" href="#creating-an-aggregation-builder" title="Permalink to this headline"></a></h2>
<p>You can easily create a new <code class="docutils literal"><span class="pre">Aggregation\Builder</span></code> object with the
<code class="docutils literal"><span class="pre">DocumentManager::createAggregationBuilder()</span></code> method:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\User</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
</pre></div>
</div>
<p>The first argument indicates the document for which you want to create the
builder.</p>
<div class="section" id="adding-pipeline-stages">
<h3>Adding pipeline stages<a class="headerlink" href="#adding-pipeline-stages" title="Permalink to this headline"></a></h3>
<p>To add a pipeline stage to the builder, call the corresponding method on the
builder object:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\Orders</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$builder</span>
<span class="o">-&gt;</span><span class="na">match</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;purchaseDate&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">gte</span><span class="p">(</span><span class="nv">$from</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">lt</span><span class="p">(</span><span class="nv">$to</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;user&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">references</span><span class="p">(</span><span class="nv">$user</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">group</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">expression</span><span class="p">(</span><span class="s1">&#39;$user&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;numPurchases&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">sum</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;amount&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">sum</span><span class="p">(</span><span class="s1">&#39;$amount&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>Just like the query builder, the aggregation builder takes care of converting
<code class="docutils literal"><span class="pre">DateTime</span></code> objects into <code class="docutils literal"><span class="pre">MongoDate</span></code> objects.</p>
</div>
<div class="section" id="nesting-expressions">
<h3>Nesting expressions<a class="headerlink" href="#nesting-expressions" title="Permalink to this headline"></a></h3>
<p>You can create more complex aggregation stages by using the <code class="docutils literal"><span class="pre">expr()</span></code> method in
the aggregation builder.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\Orders</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$builder</span>
<span class="o">-&gt;</span><span class="na">match</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;purchaseDate&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">gte</span><span class="p">(</span><span class="nv">$from</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">lt</span><span class="p">(</span><span class="nv">$to</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;user&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">references</span><span class="p">(</span><span class="nv">$user</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">group</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">expression</span><span class="p">(</span>
<span class="nv">$builder</span><span class="o">-&gt;</span><span class="na">expr</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;month&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">month</span><span class="p">(</span><span class="s1">&#39;purchaseDate&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;year&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">year</span><span class="p">(</span><span class="s1">&#39;purchaseDate&#39;</span><span class="p">)</span>
<span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;numPurchases&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">sum</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;amount&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">sum</span><span class="p">(</span><span class="s1">&#39;$amount&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>This aggregation would group all purchases by their month and year by projecting
those values into an embedded object for the <code class="docutils literal"><span class="pre">id</span></code> field. For example:</p>
<div class="highlight-json"><div class="highlight"><pre>{
_id: {
month: 1,
year: 2016
},
numPurchases: 1,
amount: 27.89
}
</pre></div>
</div>
</div>
<div class="section" id="executing-an-aggregation-pipeline">
<h3>Executing an aggregation pipeline<a class="headerlink" href="#executing-an-aggregation-pipeline" title="Permalink to this headline"></a></h3>
<p>You can execute a pipeline using the <code class="docutils literal"><span class="pre">execute()</span></code> method. This will run the
aggregation pipeline and return a cursor for you to iterate over the results:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\User</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$result</span> <span class="o">=</span> <span class="nv">$builder</span><span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
</pre></div>
</div>
<p>If you instead want to look at the built aggregation pipeline, call the
<code class="docutils literal"><span class="pre">Builder::getPipeline()</span></code> method.</p>
</div>
<div class="section" id="hydration">
<h3>Hydration<a class="headerlink" href="#hydration" title="Permalink to this headline"></a></h3>
<p>By default, aggregation results are returned as PHP arrays. This is because the
result of an aggregation pipeline may look completely different from the source
document. In order to get hydrated aggregation results, you first have to map
a <code class="docutils literal"><span class="pre">QueryResultDocument</span></code>. These are written like regular mapped documents, but
they can't be persisted to the database.</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="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
<span class="sd">/** @QueryResultDocument */</span>
<span class="k">class</span> <span class="nc">UserPurchases</span>
<span class="p">{</span>
<span class="sd">/** @ReferenceOne(targetDocument=&quot;User&quot;, name=&quot;_id&quot;) */</span>
<span class="k">private</span> <span class="nv">$user</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;int&quot;) */</span>
<span class="k">private</span> <span class="nv">$numPurchases</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;float&quot;) */</span>
<span class="k">private</span> <span class="nv">$amount</span><span class="p">;</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;query-result-document</span> <span class="na">name=</span><span class="s">&quot;Documents\UserPurchases&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;field</span> <span class="na">fieldName=</span><span class="s">&quot;numPurchases&quot;</span> <span class="na">type=</span><span class="s">&quot;int&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;field</span> <span class="na">fieldName=</span><span class="s">&quot;amount&quot;</span> <span class="na">type=</span><span class="s">&quot;float&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;reference-one</span> <span class="na">field=</span><span class="s">&quot;user&quot;</span> <span class="na">target-document=</span><span class="s">&quot;Documents\User&quot;</span> <span class="na">name=</span><span class="s">&quot;_id&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/query-result-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">Documents\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">queryResultDocument</span>
<span class="l l-Scalar l-Scalar-Plain">fields</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">user</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">name</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">_id</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\User</span>
<span class="l l-Scalar l-Scalar-Plain">numPurchases</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">int</span>
<span class="l l-Scalar l-Scalar-Plain">amount</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">float</span>
</pre></div>
</div>
</li>
</ul>
</div>
<p>Once you have mapped the document, use the <code class="docutils literal"><span class="pre">hydrate()</span></code> method to tell the
aggregation builder about this document:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\Orders</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$builder</span>
<span class="o">-&gt;</span><span class="na">hydrate</span><span class="p">(</span><span class="nx">\Documents\UserPurchases</span><span class="o">::</span><span class="na">class</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">match</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;purchaseDate&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">gte</span><span class="p">(</span><span class="nv">$from</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">lt</span><span class="p">(</span><span class="nv">$to</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;user&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">references</span><span class="p">(</span><span class="nv">$user</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">group</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">expression</span><span class="p">(</span><span class="s1">&#39;$user&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;numPurchases&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">sum</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;amount&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">sum</span><span class="p">(</span><span class="s1">&#39;$amount&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>When you run the queries, all results will be returned as instances of the
specified document.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Query result documents can use all features regular documents can use: you
can map embedded documents, define references, and even use discriminators
to get different result documents according to the aggregation result.</p>
</div>
</div>
</div>
<div class="section" id="aggregation-pipeline-stages">
<h2>Aggregation pipeline stages<a class="headerlink" href="#aggregation-pipeline-stages" title="Permalink to this headline"></a></h2>
<p>MongoDB provides the following aggregation pipeline stages:</p>
<ul class="simple">
<li><a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/addFields/">$addFields</a></li>
<li><a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/bucket/">$bucket</a></li>
<li><a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/bucketAuto/">$bucketAuto</a></li>
<li><a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/collStats/">$collStats</a></li>
<li><a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/count/">$count</a></li>
<li><a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/facet/">$facet</a></li>
<li><a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/geoNear/">$geoNear</a></li>
<li><a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/graphLookup/">$graphLookup</a></li>
<li><a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/group/">$group</a></li>
<li><a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/indexStats/">$indexStats</a></li>
<li><a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/limit/">$limit</a></li>
<li><a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/">$lookup</a></li>
<li><a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/match/">$match</a></li>
<li><a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/out/">$out</a></li>
<li><a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/project/">$project</a></li>
<li><a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/redact/">$redact</a></li>
<li><a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/replaceRoot/">$replaceRoot</a></li>
<li><a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/sample/">$sample</a></li>
<li><a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/skip/">$skip</a></li>
<li><a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/project/">$sort</a></li>
<li><a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/sortByCount/">$sortByCount</a></li>
<li><a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/unwind/">$unwind</a></li>
</ul>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">The <code class="docutils literal"><span class="pre">$lookup</span></code>, <code class="docutils literal"><span class="pre">$sample</span></code> and <code class="docutils literal"><span class="pre">$indexStats</span></code> stages were added in MongoDB
3.2. The <code class="docutils literal"><span class="pre">$addFields</span></code>, <code class="docutils literal"><span class="pre">$bucket</span></code>, <code class="docutils literal"><span class="pre">$bucketAuto</span></code>, <code class="docutils literal"><span class="pre">$sortByCount</span></code>,
<code class="docutils literal"><span class="pre">$replaceRoot</span></code>, <code class="docutils literal"><span class="pre">$facet</span></code>, <code class="docutils literal"><span class="pre">$graphLookup</span></code>, <code class="docutils literal"><span class="pre">$coun</span></code> and <code class="docutils literal"><span class="pre">$collStats</span></code>
stages were added in MongoDB 3.4.</p>
</div>
<div class="section" id="id1">
<h3>$addFields<a class="headerlink" href="#id1" title="Permalink to this headline"></a></h3>
<p>Adds new fields to documents. <code class="docutils literal"><span class="pre">$addFields</span></code> outputs documents that contain all
existing fields from the input documents and newly added fields.</p>
<p>The <code class="docutils literal"><span class="pre">$addFields</span></code> stage is equivalent to a <code class="docutils literal"><span class="pre">$project</span></code> stage that explicitly
specifies all existing fields in the input documents and adds the new fields.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\Orders</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$builder</span>
<span class="o">-&gt;</span><span class="na">addFields</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;purchaseYear&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">year</span><span class="p">(</span><span class="s1">&#39;$purchaseDate&#39;</span><span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="id2">
<h3>$bucket<a class="headerlink" href="#id2" title="Permalink to this headline"></a></h3>
<p>Categorizes incoming documents into groups, called buckets, based on a specified
expression and bucket boundaries.</p>
<p>Each bucket is represented as a document in the output. The document for each
bucket contains an _id field, whose value specifies the inclusive lower bound of
the bucket and a count field that contains the number of documents in the bucket.
The count field is included by default when the output is not specified.</p>
<p><code class="docutils literal"><span class="pre">$bucket</span></code> only produces output documents for buckets that contain at least one
input document.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\Orders</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$builder</span>
<span class="o">-&gt;</span><span class="na">bucket</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">groupBy</span><span class="p">(</span><span class="s1">&#39;$itemCount&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">boundaries</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="s1">&#39;5+&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">defaultBucket</span><span class="p">(</span><span class="s1">&#39;5+&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">output</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;lowestValue&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">min</span><span class="p">(</span><span class="s1">&#39;$value&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;highestValue&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">max</span><span class="p">(</span><span class="s1">&#39;$value&#39;</span><span class="p">)</span>
<span class="p">;</span>
</pre></div>
</div>
</div>
<div class="section" id="id3">
<h3>$bucketAuto<a class="headerlink" href="#id3" title="Permalink to this headline"></a></h3>
<p>Similar to <code class="docutils literal"><span class="pre">$bucket</span></code>, except that boundaries are automatically determined in
an attempt to evenly distribute the documents into the specified number of
buckets.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\Orders</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$builder</span>
<span class="o">-&gt;</span><span class="na">bucketAuto</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">groupBy</span><span class="p">(</span><span class="s1">&#39;$itemCount&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">buckets</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">output</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;lowestValue&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">min</span><span class="p">(</span><span class="s1">&#39;$value&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;highestValue&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">max</span><span class="p">(</span><span class="s1">&#39;$value&#39;</span><span class="p">)</span>
<span class="p">;</span>
</pre></div>
</div>
</div>
<div class="section" id="id4">
<h3>$collStats<a class="headerlink" href="#id4" title="Permalink to this headline"></a></h3>
<p>The <code class="docutils literal"><span class="pre">$collStats</span></code> stage returns statistics regarding a collection or view.</p>
</div>
<div class="section" id="id5">
<h3>$count<a class="headerlink" href="#id5" title="Permalink to this headline"></a></h3>
<p>Returns a document that contains a count of the number of documents input to the
stage.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\Orders</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$builder</span>
<span class="o">-&gt;</span><span class="na">match</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;itemCount&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">eq</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">count</span><span class="p">(</span><span class="s1">&#39;numSingleItemOrders&#39;</span><span class="p">)</span>
<span class="p">;</span>
</pre></div>
</div>
<p>The example above returns a single document with the <code class="docutils literal"><span class="pre">numSingleItemOrders</span></code>
containing the number of orders found.</p>
</div>
<div class="section" id="id6">
<h3>$facet<a class="headerlink" href="#id6" title="Permalink to this headline"></a></h3>
<p>Processes multiple aggregation pipelines within a single stage on the same set
of input documents. Each sub-pipeline has its own field in the output document
where its results are stored as an array of documents.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\Orders</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$builder</span>
<span class="o">-&gt;</span><span class="na">facet</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;groupedByItemCount&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">pipeline</span><span class="p">(</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\Orders</span><span class="o">::</span><span class="na">class</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">group</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">expression</span><span class="p">(</span><span class="s1">&#39;$itemCount&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;lowestValue&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">min</span><span class="p">(</span><span class="s1">&#39;$value&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;highestValue&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">max</span><span class="p">(</span><span class="s1">&#39;$value&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;totalValue&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">sum</span><span class="p">(</span><span class="s1">&#39;$value&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;averageValue&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">avg</span><span class="p">(</span><span class="s1">&#39;$value&#39;</span><span class="p">)</span>
<span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;groupedByYear&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">pipeline</span><span class="p">(</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\Orders</span><span class="o">::</span><span class="na">class</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">group</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">year</span><span class="p">(</span><span class="s1">&#39;purchaseDate&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;lowestValue&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">min</span><span class="p">(</span><span class="s1">&#39;$value&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;highestValue&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">max</span><span class="p">(</span><span class="s1">&#39;$value&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;totalValue&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">sum</span><span class="p">(</span><span class="s1">&#39;$value&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;averageValue&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">avg</span><span class="p">(</span><span class="s1">&#39;$value&#39;</span><span class="p">)</span>
<span class="p">)</span>
<span class="p">;</span>
</pre></div>
</div>
</div>
<div class="section" id="id7">
<h3>$geoNear<a class="headerlink" href="#id7" title="Permalink to this headline"></a></h3>
<p>The <code class="docutils literal"><span class="pre">$geoNear</span></code> stage finds and outputs documents in order of nearest to
farthest from a specified point.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\City</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$builder</span>
<span class="o">-&gt;</span><span class="na">geoNear</span><span class="p">(</span><span class="mi">120</span><span class="p">,</span> <span class="mi">40</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">spherical</span><span class="p">(</span><span class="k">true</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">distanceField</span><span class="p">(</span><span class="s1">&#39;distance&#39;</span><span class="p">)</span>
<span class="c1">// Convert radians to kilometers (use 3963.192 for miles)</span>
<span class="o">-&gt;</span><span class="na">distanceMultiplier</span><span class="p">(</span><span class="mf">6378.137</span><span class="p">);</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">The <code class="docutils literal"><span class="pre">$geoNear</span></code> stage must be the first stage in the pipeline and the
collection must contain a single geospatial index. You must include the
<code class="docutils literal"><span class="pre">distanceField</span></code> option for the stage to work.</p>
</div>
</div>
<div class="section" id="id8">
<h3>$graphLookup<a class="headerlink" href="#id8" title="Permalink to this headline"></a></h3>
<p>Performs a recursive search on a collection, with options for restricting the
search by recursion depth and query filter. The <code class="docutils literal"><span class="pre">$graphLookup</span></code> stage can be
used to resolve association graphs and flatten them into a single list.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\Traveller</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$builder</span>
<span class="o">-&gt;</span><span class="na">graphLookup</span><span class="p">(</span><span class="s1">&#39;nearestAirport&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">connectFromField</span><span class="p">(</span><span class="s1">&#39;connections&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">maxDepth</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">depthField</span><span class="p">(</span><span class="s1">&#39;numConnections&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">alias</span><span class="p">(</span><span class="s1">&#39;destinations&#39;</span><span class="p">);</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">The target document of the reference used in <code class="docutils literal"><span class="pre">connectFromField</span></code> must be
the very same document. The aggregation builder will throw an exception if
you try to resolve a different document.</p>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Due to a limitation in MongoDB, the <code class="docutils literal"><span class="pre">$graphLookup</span></code> stage can not be used
with references that are stored as DBRef. To use references in a
<code class="docutils literal"><span class="pre">$graphLookup</span></code> stage, store the reference as ID or <code class="docutils literal"><span class="pre">ref</span></code>. This is
explained in the <a class="reference internal" href="reference-mapping.html"><span class="doc">Reference mapping</span></a> chapter.</p>
</div>
</div>
<div class="section" id="aggregation-builder-group">
<span id="id9"></span><h3>$group<a class="headerlink" href="#aggregation-builder-group" title="Permalink to this headline"></a></h3>
<p>The <code class="docutils literal"><span class="pre">$group</span></code> stage is used to do calculations based on previously matched
documents:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\Orders</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$builder</span>
<span class="o">-&gt;</span><span class="na">match</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;user&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">references</span><span class="p">(</span><span class="nv">$user</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">group</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">expression</span><span class="p">(</span>
<span class="nv">$builder</span><span class="o">-&gt;</span><span class="na">expr</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;month&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">month</span><span class="p">(</span><span class="s1">&#39;purchaseDate&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;year&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">year</span><span class="p">(</span><span class="s1">&#39;purchaseDate&#39;</span><span class="p">)</span>
<span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;numPurchases&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">sum</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;amount&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">sum</span><span class="p">(</span><span class="s1">&#39;$amount&#39;</span><span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="id10">
<h3>$indexStats<a class="headerlink" href="#id10" title="Permalink to this headline"></a></h3>
<p>The <code class="docutils literal"><span class="pre">$indexStats</span></code> stage returns statistics regarding the use of each index for
the collection. More information can be found in the <a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/indexStats/">official Documentation</a></p>
</div>
<div class="section" id="id11">
<h3>$lookup<a class="headerlink" href="#id11" title="Permalink to this headline"></a></h3>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">The <code class="docutils literal"><span class="pre">$lookup</span></code> stage was introduced in MongoDB 3.2. Using it on older servers
will result in an error.</p>
</div>
<p>The <code class="docutils literal"><span class="pre">$lookup</span></code> stage is used to fetch documents from different collections in
pipeline stages. Take the following relationship for example:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/**</span>
<span class="sd"> * @ReferenceMany(</span>
<span class="sd"> * targetDocument=&quot;Documents\Item&quot;,</span>
<span class="sd"> * cascade=&quot;all&quot;,</span>
<span class="sd"> * storeAs=&quot;id&quot;</span>
<span class="sd"> * )</span>
<span class="sd"> */</span>
<span class="k">private</span> <span class="nv">$items</span><span class="p">;</span>
</pre></div>
</div>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\Orders</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$builder</span>
<span class="o">-&gt;</span><span class="na">lookup</span><span class="p">(</span><span class="s1">&#39;items&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">alias</span><span class="p">(</span><span class="s1">&#39;items&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>The resulting array will contain all matched item documents in an array. This has
to be considered when looking up one-to-one relationships:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/**</span>
<span class="sd"> * @ReferenceOne(</span>
<span class="sd"> * targetDocument=&quot;Documents\Item&quot;,</span>
<span class="sd"> * cascade=&quot;all&quot;,</span>
<span class="sd"> * storeAs=&quot;id&quot;</span>
<span class="sd"> * )</span>
<span class="sd"> */</span>
<span class="k">private</span> <span class="nv">$items</span><span class="p">;</span>
</pre></div>
</div>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\Orders</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$builder</span>
<span class="o">-&gt;</span><span class="na">lookup</span><span class="p">(</span><span class="s1">&#39;user&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">alias</span><span class="p">(</span><span class="s1">&#39;user&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">unwind</span><span class="p">(</span><span class="s1">&#39;$user&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>MongoDB will always return an array, even if the lookup only returned a single
document. Thus, when looking up one-to-one references the result must be flattened
using the <code class="docutils literal"><span class="pre">$unwind</span></code> operator.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Due to a limitation in MongoDB, the <code class="docutils literal"><span class="pre">$lookup</span></code> stage can not be used with
references that are stored as DBRef. To use references in a <code class="docutils literal"><span class="pre">$lookup</span></code>
stage, store the reference as ID or <code class="docutils literal"><span class="pre">ref</span></code>. This is explained in the
<a class="reference internal" href="reference-mapping.html"><span class="doc">Reference mapping</span></a> chapter.</p>
</div>
<p>You can also configure your lookup manually if you don't have it mapped in your
document:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\Orders</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$builder</span>
<span class="o">-&gt;</span><span class="na">lookup</span><span class="p">(</span><span class="s1">&#39;unmappedCollection&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">localField</span><span class="p">(</span><span class="s1">&#39;_id&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">foreignField</span><span class="p">(</span><span class="s1">&#39;userId&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">alias</span><span class="p">(</span><span class="s1">&#39;items&#39;</span><span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="id12">
<h3>$match<a class="headerlink" href="#id12" title="Permalink to this headline"></a></h3>
<p>The <code class="docutils literal"><span class="pre">$match</span></code> stage lets you filter documents according to certain criteria. It
works just like the query builder:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\Orders</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$builder</span>
<span class="o">-&gt;</span><span class="na">match</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;purchaseDate&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">gte</span><span class="p">(</span><span class="nv">$from</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">lt</span><span class="p">(</span><span class="nv">$to</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;user&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">references</span><span class="p">(</span><span class="nv">$user</span><span class="p">);</span>
</pre></div>
</div>
<p>You can also use fields defined in previous stages:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\Orders</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$builder</span>
<span class="o">-&gt;</span><span class="na">project</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">excludeIdField</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">includeFields</span><span class="p">([</span><span class="s1">&#39;purchaseDate&#39;</span><span class="p">,</span> <span class="s1">&#39;user&#39;</span><span class="p">])</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;purchaseYear&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">year</span><span class="p">(</span><span class="s1">&#39;$purchaseDate&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">match</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;purchaseYear&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">equals</span><span class="p">(</span><span class="mi">2016</span><span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="id13">
<h3>$out<a class="headerlink" href="#id13" title="Permalink to this headline"></a></h3>
<p>The <code class="docutils literal"><span class="pre">$out</span></code> stage is used to store the result of the aggregation pipeline in a
collection instead of returning an iterable cursor of results. This must be the
last stage in an aggregation pipeline.</p>
<p>If the collection specified by the <code class="docutils literal"><span class="pre">$out</span></code> operation already exists, then upon
completion of the aggregation, the existing collection is atomically replaced.
Any indexes that existed on the collection are left intact. If the aggregation
fails, the <code class="docutils literal"><span class="pre">$out</span></code> operation does not remove the data from an existing
collection.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">The aggregation pipeline will fail to complete if the result would violate
any unique index constraints, including those on the <code class="docutils literal"><span class="pre">id</span></code> field.</p>
</div>
</div>
<div class="section" id="id14">
<h3>$project<a class="headerlink" href="#id14" title="Permalink to this headline"></a></h3>
<p>The <code class="docutils literal"><span class="pre">$project</span></code> stage lets you reshape the current document or define a completely
new one:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\Orders</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$builder</span>
<span class="o">-&gt;</span><span class="na">project</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">excludeIdField</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">includeFields</span><span class="p">([</span><span class="s1">&#39;purchaseDate&#39;</span><span class="p">,</span> <span class="s1">&#39;user&#39;</span><span class="p">])</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;purchaseYear&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">year</span><span class="p">(</span><span class="s1">&#39;$purchaseDate&#39;</span><span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="id15">
<h3>$redact<a class="headerlink" href="#id15" title="Permalink to this headline"></a></h3>
<p>The redact stage can be used to restrict the contents of the documents based on
information stored in the documents themselves. You can read more about the
<code class="docutils literal"><span class="pre">$redact</span></code> stage in the <a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/aggregation/redact/">MongoDB documentation</a>.</p>
<p>The following example taken from the official documentation checks the <code class="docutils literal"><span class="pre">level</span></code>
field on all document levels and evaluates it to grant or deny access:</p>
<div class="highlight-json"><div class="highlight"><pre>{
_id: 1,
level: 1,
acct_id: &quot;xyz123&quot;,
cc: {
level: 5,
type: &quot;yy&quot;,
num: 000000000000,
exp_date: ISODate(&quot;2015-11-01T00:00:00.000Z&quot;),
billing_addr: {
level: 5,
addr1: &quot;123 ABC Street&quot;,
city: &quot;Some City&quot;
},
shipping_addr: [
{
level: 3,
addr1: &quot;987 XYZ Ave&quot;,
city: &quot;Some City&quot;
},
{
level: 3,
addr1: &quot;PO Box 0123&quot;,
city: &quot;Some City&quot;
}
]
},
status: &quot;A&quot;
}
</pre></div>
</div>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\Orders</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$builder</span>
<span class="o">-&gt;</span><span class="na">redact</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">cond</span><span class="p">(</span>
<span class="nv">$builder</span><span class="o">-&gt;</span><span class="na">expr</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">gte</span><span class="p">(</span><span class="s1">&#39;$$level&#39;</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span>
<span class="s1">&#39;$$PRUNE&#39;</span><span class="p">,</span>
<span class="s1">&#39;$$DESCEND&#39;</span>
<span class="p">)</span>
</pre></div>
</div>
</div>
<div class="section" id="id16">
<h3>$replaceRoot<a class="headerlink" href="#id16" title="Permalink to this headline"></a></h3>
<p>Promotes a specified document to the top level and replaces all other fields.
The operation replaces all existing fields in the input document, including the
<code class="docutils literal"><span class="pre">_id</span></code> field. You can promote an existing embedded document to the top level,
or create a new document for promotion.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\Orders</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$builder</span>
<span class="o">-&gt;</span><span class="na">replaceRoot</span><span class="p">(</span><span class="s1">&#39;$embeddedField&#39;</span><span class="p">);</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\Orders</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$builder</span>
<span class="o">-&gt;</span><span class="na">replaceRoot</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;averagePricePerItem&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">divide</span><span class="p">(</span><span class="s1">&#39;$value&#39;</span><span class="p">,</span> <span class="s1">&#39;$itemCount&#39;</span><span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="id17">
<h3>$sample<a class="headerlink" href="#id17" title="Permalink to this headline"></a></h3>
<p>The sample stage can be used to randomly select a subset of documents in the
aggregation pipeline. It behaves like the <code class="docutils literal"><span class="pre">$limit</span></code> stage, but instead of
returning the first <code class="docutils literal"><span class="pre">n</span></code> documents it returns <code class="docutils literal"><span class="pre">n</span></code> random documents.</p>
</div>
<div class="section" id="sort-limit-and-skip">
<h3>$sort, $limit and $skip<a class="headerlink" href="#sort-limit-and-skip" title="Permalink to this headline"></a></h3>
<p>The <code class="docutils literal"><span class="pre">$sort</span></code>, <code class="docutils literal"><span class="pre">$limit</span></code> and <code class="docutils literal"><span class="pre">$skip</span></code> stages behave like the corresponding
query options, allowing you to control the order and subset of results returned
by the aggregation pipeline.</p>
</div>
<div class="section" id="id18">
<h3>$sortByCount<a class="headerlink" href="#id18" title="Permalink to this headline"></a></h3>
<p>Groups incoming documents based on the value of a specified expression, then
computes the count of documents in each distinct group.</p>
<p>Each output document contains two fields: an _id field containing the distinct
grouping value, and a count field containing the number of documents belonging
to that grouping or category.</p>
<p>The documents are sorted by count in descending order.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\Orders</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$builder</span><span class="o">-&gt;</span><span class="na">sortByCount</span><span class="p">(</span><span class="s1">&#39;$items&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>The example above is equivalent to the following pipeline:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\Orders</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$builder</span>
<span class="o">-&gt;</span><span class="na">group</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;_id&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">expression</span><span class="p">(</span><span class="s1">&#39;$items&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;count&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">sum</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">sort</span><span class="p">([</span><span class="s1">&#39;count&#39;</span> <span class="o">=&gt;</span> <span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="p">;</span>
</pre></div>
</div>
</div>
<div class="section" id="id19">
<h3>$unwind<a class="headerlink" href="#id19" title="Permalink to this headline"></a></h3>
<p>The <code class="docutils literal"><span class="pre">$unwind</span></code> stage flattens an array in a document, returning a copy for each
item. Take this sample document:</p>
<div class="highlight-json"><div class="highlight"><pre>{
_id: {
month: 1,
year: 2016
},
purchaseDates: [
&#39;2016-01-07&#39;,
&#39;2016-03-10&#39;,
&#39;2016-06-25&#39;
]
}
</pre></div>
</div>
<p>To flatten the <code class="docutils literal"><span class="pre">purchaseDates</span></code> array, we would apply the following pipeline
stage:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$builder</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createAggregationBuilder</span><span class="p">(</span><span class="nx">\Documents\User</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$builder</span><span class="o">-&gt;</span><span class="na">unwind</span><span class="p">(</span><span class="s1">&#39;$purchaseDates&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>The stage would return three documents, each containing a single purchase date:</p>
<div class="highlight-json"><div class="highlight"><pre>{
_id: {
month: 1,
year: 2016
},
purchaseDates: &#39;2016-01-07&#39;
},
{
_id: {
month: 1,
year: 2016
},
purchaseDates: &#39;2016-03-10&#39;
},
{
_id: {
month: 1,
year: 2016
},
purchaseDates: &#39;2016-06-25&#39;
}
</pre></div>
</div>
</div>
</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="#">Aggregation builder</a><ul>
<li><a class="reference internal" href="#creating-an-aggregation-builder">Creating an Aggregation Builder</a><ul>
<li><a class="reference internal" href="#adding-pipeline-stages">Adding pipeline stages</a></li>
<li><a class="reference internal" href="#nesting-expressions">Nesting expressions</a></li>
<li><a class="reference internal" href="#executing-an-aggregation-pipeline">Executing an aggregation pipeline</a></li>
<li><a class="reference internal" href="#hydration">Hydration</a></li>
</ul>
</li>
<li><a class="reference internal" href="#aggregation-pipeline-stages">Aggregation pipeline stages</a><ul>
<li><a class="reference internal" href="#id1">$addFields</a></li>
<li><a class="reference internal" href="#id2">$bucket</a></li>
<li><a class="reference internal" href="#id3">$bucketAuto</a></li>
<li><a class="reference internal" href="#id4">$collStats</a></li>
<li><a class="reference internal" href="#id5">$count</a></li>
<li><a class="reference internal" href="#id6">$facet</a></li>
<li><a class="reference internal" href="#id7">$geoNear</a></li>
<li><a class="reference internal" href="#id8">$graphLookup</a></li>
<li><a class="reference internal" href="#aggregation-builder-group">$group</a></li>
<li><a class="reference internal" href="#id10">$indexStats</a></li>
<li><a class="reference internal" href="#id11">$lookup</a></li>
<li><a class="reference internal" href="#id12">$match</a></li>
<li><a class="reference internal" href="#id13">$out</a></li>
<li><a class="reference internal" href="#id14">$project</a></li>
<li><a class="reference internal" href="#id15">$redact</a></li>
<li><a class="reference internal" href="#id16">$replaceRoot</a></li>
<li><a class="reference internal" href="#id17">$sample</a></li>
<li><a class="reference internal" href="#sort-limit-and-skip">$sort, $limit and $skip</a></li>
<li><a class="reference internal" href="#id18">$sortByCount</a></li>
<li><a class="reference internal" href="#id19">$unwind</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/aggregation-builder.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>
@@ -0,0 +1,271 @@
<!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>Architecture &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="architecture">
<h1>Architecture<a class="headerlink" href="#architecture" title="Permalink to this headline"></a></h1>
<p>This chapter gives an overview of the overall architecture,
terminology and constraints of Doctrine. It is recommended to
read this chapter carefully.</p>
<div class="section" id="documents">
<h2>Documents<a class="headerlink" href="#documents" title="Permalink to this headline"></a></h2>
<p>A document is a lightweight, persistent domain object. A document can
be any regular PHP class observing the following restrictions:</p>
<ul class="simple">
<li>A document class must not be final or contain final methods.</li>
<li>All persistent properties/field of any document class should
always be private or protected, otherwise lazy-loading might not
work as expected.</li>
<li>A document class must not implement <code class="docutils literal"><span class="pre">__clone</span></code> or
<a class="reference internal" href="../cookbook/implementing-wakeup-or-clone.html"><span class="doc">do so safely</span></a>.</li>
<li>A document class must not implement <code class="docutils literal"><span class="pre">__wakeup</span></code> or
<a class="reference internal" href="../cookbook/implementing-wakeup-or-clone.html"><span class="doc">do so safely</span></a>.
Also consider implementing
<a class="reference external" href="http://de3.php.net/manual/en/class.serializable.php">Serializable</a>
instead.</li>
<li>Any two document classes in a class hierarchy that inherit
directly or indirectly from one another must not have a mapped
property with the same name. That is, if B inherits from A then B
must not have a mapped field with the same name as an already
mapped field that is inherited from A.</li>
</ul>
<p>Documents support inheritance, polymorphic associations, and
polymorphic queries. Both abstract and concrete classes can be
documents. Documents may extend non-document classes as well as document
classes, and non-document classes may extend document classes.</p>
<div class="admonition tip">
<p class="first admonition-title">Tip</p>
<p class="last">The constructor of a document is only ever invoked when
<em>you</em> construct a new instance with the <em>new</em> keyword. Doctrine
never calls document constructors, thus you are free to use them as
you wish and even have it require arguments of any type.</p>
</div>
<div class="section" id="document-states">
<h3>Document states<a class="headerlink" href="#document-states" title="Permalink to this headline"></a></h3>
<p>A document instance can be characterized as being NEW, MANAGED, DETACHED or REMOVED.</p>
<ul class="simple">
<li>A NEW document instance has no persistent identity, and is not yet
associated with a DocumentManager and a UnitOfWork (i.e. those just
created with the &quot;new&quot; operator).</li>
<li>A MANAGED document instance is an instance with a persistent
identity that is associated with a DocumentManager and whose
persistence is thus managed.</li>
<li>A DETACHED document instance is an instance with a persistent
identity that is not (or no longer) associated with a
DocumentManager and a UnitOfWork.</li>
<li>A REMOVED document instance is an instance with a persistent
identity, associated with a DocumentManager, that will be removed
from the database upon transaction commit.</li>
</ul>
</div>
<div class="section" id="persistent-fields">
<h3>Persistent fields<a class="headerlink" href="#persistent-fields" title="Permalink to this headline"></a></h3>
<p>The persistent state of a document is represented by instance
variables. An instance variable must be directly accessed only from
within the methods of the document by the document instance itself.
Instance variables must not be accessed by clients of the document.
The state of the document is available to clients only through the
document's methods, i.e. accessor methods (getter/setter methods) or
other business methods.</p>
<p>Collection-valued persistent fields and properties must be defined
in terms of the <code class="docutils literal"><span class="pre">Doctrine\Common\Collections\Collection</span></code>
interface. The collection implementation type may be used by the
application to initialize fields or properties before the document is
made persistent. Once the document becomes managed (or detached),
subsequent access must be through the interface type.</p>
</div>
<div class="section" id="serializing-documents">
<h3>Serializing documents<a class="headerlink" href="#serializing-documents" title="Permalink to this headline"></a></h3>
<p>Serializing documents can be problematic and is not really
recommended, at least not as long as a document instance still holds
references to proxy objects or is still managed by an
DocumentManager. If you intend to serialize (and unserialize) document
instances that still hold references to proxy objects you may run
into problems with private properties because of technical
limitations. Proxy objects implement <code class="docutils literal"><span class="pre">__sleep</span></code> and it is not
possible for <code class="docutils literal"><span class="pre">__sleep</span></code> to return names of private properties in
parent classes. On the other hand it is not a solution for proxy
objects to implement <code class="docutils literal"><span class="pre">Serializable</span></code> because Serializable does not
work well with any potential cyclic object references (at least we
did not find a way yet, if you did, please contact us).</p>
</div>
</div>
<div class="section" id="the-documentmanager">
<h2>The DocumentManager<a class="headerlink" href="#the-documentmanager" title="Permalink to this headline"></a></h2>
<p>The <code class="docutils literal"><span class="pre">DocumentManager</span></code> class is a central access point to the ODM
functionality provided by Doctrine. The <code class="docutils literal"><span class="pre">DocumentManager</span></code> API is
used to manage the persistence of your objects and to query for
persistent objects.</p>
<div class="section" id="transactional-write-behind">
<h3>Transactional write-behind<a class="headerlink" href="#transactional-write-behind" title="Permalink to this headline"></a></h3>
<p>An <code class="docutils literal"><span class="pre">DocumentManager</span></code> and the underlying <code class="docutils literal"><span class="pre">UnitOfWork</span></code> employ a
strategy called &quot;transactional write-behind&quot; that delays the
execution of query statements in order to execute them in the most
efficient way and to execute them at the end of a transaction so
that all write locks are quickly released. You should see Doctrine
as a tool to synchronize your in-memory objects with the database
in well defined units of work. Work with your objects and modify
them as usual and when you're done call <code class="docutils literal"><span class="pre">DocumentManager#flush()</span></code>
to make your changes persistent.</p>
</div>
<div class="section" id="the-unit-of-work">
<h3>The Unit of Work<a class="headerlink" href="#the-unit-of-work" title="Permalink to this headline"></a></h3>
<p>Internally an <code class="docutils literal"><span class="pre">DocumentManager</span></code> uses a <code class="docutils literal"><span class="pre">UnitOfWork</span></code>, which is a
typical implementation of the
<a class="reference external" href="http://martinfowler.com/eaaCatalog/unitOfWork.html">Unit of Work pattern</a>,
to keep track of all the things that need to be done the next time
<code class="docutils literal"><span class="pre">flush</span></code> is invoked. You usually do not directly interact with a
<code class="docutils literal"><span class="pre">UnitOfWork</span></code> but with the <code class="docutils literal"><span class="pre">DocumentManager</span></code> instead.</p>
</div>
</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="#">Architecture</a><ul>
<li><a class="reference internal" href="#documents">Documents</a><ul>
<li><a class="reference internal" href="#document-states">Document states</a></li>
<li><a class="reference internal" href="#persistent-fields">Persistent fields</a></li>
<li><a class="reference internal" href="#serializing-documents">Serializing documents</a></li>
</ul>
</li>
<li><a class="reference internal" href="#the-documentmanager">The DocumentManager</a><ul>
<li><a class="reference internal" href="#transactional-write-behind">Transactional write-behind</a></li>
<li><a class="reference internal" href="#the-unit-of-work">The Unit of Work</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/architecture.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>
@@ -0,0 +1,747 @@
<!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>Basic 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="basic-mapping">
<h1>Basic Mapping<a class="headerlink" href="#basic-mapping" title="Permalink to this headline"></a></h1>
<p>This chapter explains the basic mapping of objects and properties.
Mapping of references and embedded documents will be covered in the
next chapter &quot;Reference Mapping&quot;.</p>
<div class="section" id="mapping-drivers">
<h2>Mapping Drivers<a class="headerlink" href="#mapping-drivers" title="Permalink to this headline"></a></h2>
<p>Doctrine provides several different ways for specifying object
document mapping metadata:</p>
<ul class="simple">
<li>Docblock Annotations</li>
<li>XML</li>
<li>YAML</li>
<li>Raw PHP Code</li>
</ul>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If you're wondering which mapping driver gives the best
performance, the answer is: None. Once the metadata of a class has
been read from the source (annotations, xml or yaml) it is stored
in an instance of the
<code class="docutils literal"><span class="pre">Doctrine\ODM\MongoDB\Mapping\ClassMetadata</span></code> class and these
instances are stored in the metadata cache. Therefore at the end of
the day all drivers perform equally well. If you're not using a
metadata cache (not recommended!) then the XML driver might have a
slight edge in performance due to the powerful native XML support
in PHP.</p>
</div>
</div>
<div class="section" id="introduction-to-docblock-annotations">
<h2>Introduction to Docblock Annotations<a class="headerlink" href="#introduction-to-docblock-annotations" title="Permalink to this headline"></a></h2>
<p>You've probably used docblock annotations in some form already,
most likely to provide documentation metadata for a tool like
<code class="docutils literal"><span class="pre">PHPDocumentor</span></code> (&#64;author, &#64;link, ...). Docblock annotations are a
tool to embed metadata inside the documentation section which can
then be processed by some tool. Doctrine generalizes the concept of
docblock annotations so that they can be used for any kind of
metadata and so that it is easy to define new docblock annotations.
In order to allow more involved annotation values and to reduce the
chances of clashes with other docblock annotations, the Doctrine
docblock annotations feature an alternative syntax that is heavily
inspired by the Annotation syntax introduced in Java 5.</p>
<p>The implementation of these enhanced docblock annotations is
located in the <code class="docutils literal"><span class="pre">Doctrine\Common\Annotations</span></code> namespace and
therefore part of the Common package. Doctrine docblock annotations
support namespaces and nested annotations among other things. The
Doctrine MongoDB ODM defines its own set of docblock annotations
for supplying object document mapping metadata.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If you're not comfortable with the concept of docblock
annotations, don't worry, as mentioned earlier Doctrine 2 provides
XML and YAML alternatives and you could easily implement your own
favorite mechanism for defining ORM metadata.</p>
</div>
</div>
<div class="section" id="persistent-classes">
<h2>Persistent classes<a class="headerlink" href="#persistent-classes" title="Permalink to this headline"></a></h2>
<p>In order to mark a class for object-relational persistence it needs
to be designated as a document. This can be done through the
<code class="docutils literal"><span class="pre">&#64;Document</span></code> marker annotation.</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="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
<span class="sd">/** @Document */</span>
<span class="k">class</span> <span class="nc">User</span>
<span class="p">{</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\User&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">Documents\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>
</pre></div>
</div>
</li>
</ul>
</div>
<p>By default, the document will be persisted to a database named
doctrine and a collection with the same name as the class name. In
order to change that, you can use the <code class="docutils literal"><span class="pre">db</span></code> and <code class="docutils literal"><span class="pre">collection</span></code>
option as follows:</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="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
<span class="sd">/** @Document(db=&quot;my_db&quot;, collection=&quot;users&quot;) */</span>
<span class="k">class</span> <span class="nc">User</span>
<span class="p">{</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\User&quot;</span> <span class="na">db=</span><span class="s">&quot;my_db&quot;</span> <span class="na">collection=</span><span class="s">&quot;users&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">Documents\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">db</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">my_db</span>
<span class="l l-Scalar l-Scalar-Plain">collection</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">users</span>
</pre></div>
</div>
</li>
</ul>
</div>
<p>Now instances of <code class="docutils literal"><span class="pre">Documents\User</span></code> will be persisted into a
collection named <code class="docutils literal"><span class="pre">users</span></code> in the database <code class="docutils literal"><span class="pre">my_db</span></code>.</p>
<p>If you want to omit the db attribute you can configure the default db
to use with the <code class="docutils literal"><span class="pre">setDefaultDB</span></code> method:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$config</span><span class="o">-&gt;</span><span class="na">setDefaultDB</span><span class="p">(</span><span class="s1">&#39;my_db&#39;</span><span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="doctrine-mapping-types">
<span id="id1"></span><h2>Doctrine Mapping Types<a class="headerlink" href="#doctrine-mapping-types" title="Permalink to this headline"></a></h2>
<p>A Doctrine Mapping Type defines the mapping between a PHP type and
an MongoDB type. You can even write your own custom mapping types.</p>
<p>Here is a quick overview of the built-in mapping types:</p>
<ul class="simple">
<li><code class="docutils literal"><span class="pre">bin</span></code></li>
<li><code class="docutils literal"><span class="pre">bin_bytearray</span></code></li>
<li><code class="docutils literal"><span class="pre">bin_custom</span></code></li>
<li><code class="docutils literal"><span class="pre">bin_func</span></code></li>
<li><code class="docutils literal"><span class="pre">bin_md5</span></code></li>
<li><code class="docutils literal"><span class="pre">bin_uuid</span></code></li>
<li><code class="docutils literal"><span class="pre">boolean</span></code></li>
<li><code class="docutils literal"><span class="pre">collection</span></code></li>
<li><code class="docutils literal"><span class="pre">custom_id</span></code></li>
<li><code class="docutils literal"><span class="pre">date</span></code></li>
<li><code class="docutils literal"><span class="pre">file</span></code></li>
<li><code class="docutils literal"><span class="pre">float</span></code></li>
<li><code class="docutils literal"><span class="pre">hash</span></code></li>
<li><code class="docutils literal"><span class="pre">id</span></code></li>
<li><code class="docutils literal"><span class="pre">int</span></code></li>
<li><code class="docutils literal"><span class="pre">key</span></code></li>
<li><code class="docutils literal"><span class="pre">object_id</span></code></li>
<li><code class="docutils literal"><span class="pre">raw</span></code></li>
<li><code class="docutils literal"><span class="pre">string</span></code></li>
<li><code class="docutils literal"><span class="pre">timestamp</span></code></li>
</ul>
<p>You can read more about the available MongoDB types on <a class="reference external" href="http://us.php.net/manual/en/mongo.types.php">php.net</a>.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">The Doctrine mapping types are used to convert the local PHP types to the MongoDB types
when persisting so that your domain is not bound to MongoDB-specific types. For example a
DateTime instance may be converted to MongoDate when you persist your documents, and vice
versa during hydration.</p>
</div>
<p>Generally, the name of each built-in mapping type hints as to how the value will be converted.
This list explains some of the less obvious mapping types:</p>
<ul class="simple">
<li><code class="docutils literal"><span class="pre">bin</span></code>: string to MongoBinData instance with a &quot;generic&quot; type (default)</li>
<li><code class="docutils literal"><span class="pre">bin_bytearray</span></code>: string to MongoBinData instance with a &quot;byte array&quot; type</li>
<li><code class="docutils literal"><span class="pre">bin_custom</span></code>: string to MongoBinData instance with a &quot;custom&quot; type</li>
<li><code class="docutils literal"><span class="pre">bin_func</span></code>: string to MongoBinData instance with a &quot;function&quot; type</li>
<li><code class="docutils literal"><span class="pre">bin_md5</span></code>: string to MongoBinData instance with a &quot;md5&quot; type</li>
<li><code class="docutils literal"><span class="pre">bin_uuid</span></code>: string to MongoBinData instance with a &quot;uuid&quot; type</li>
<li><code class="docutils literal"><span class="pre">collection</span></code>: numerically indexed array to MongoDB array</li>
<li><code class="docutils literal"><span class="pre">date</span></code>: DateTime to MongoDate</li>
<li><code class="docutils literal"><span class="pre">hash</span></code>: associative array to MongoDB object</li>
<li><code class="docutils literal"><span class="pre">id</span></code>: string to MongoId by default, but other formats are possible</li>
<li><code class="docutils literal"><span class="pre">timestamp</span></code>: string to MongoTimestamp</li>
<li><code class="docutils literal"><span class="pre">raw</span></code>: any type</li>
</ul>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If you are using the hash type, values within the associative array are
passed to MongoDB directly, without being prepared. Only formats suitable for
the Mongo driver should be used. If your hash contains values which are not
suitable you should either use an embedded document or use formats provided
by the MongoDB driver (e.g. <code class="docutils literal"><span class="pre">\MongoDate</span></code> instead of <code class="docutils literal"><span class="pre">\DateTime</span></code>).</p>
</div>
</div>
<div class="section" id="property-mapping">
<h2>Property Mapping<a class="headerlink" href="#property-mapping" title="Permalink to this headline"></a></h2>
<p>After a class has been marked as a document it can specify
mappings for its instance fields. Here we will only look at simple
fields that hold scalar values like strings, numbers, etc.
References to other objects and embedded objects are covered in the
chapter &quot;Reference Mapping&quot;.</p>
<div class="section" id="basic-mapping-identifiers">
<span id="identifiers"></span><h3>Identifiers<a class="headerlink" href="#basic-mapping-identifiers" title="Permalink to this headline"></a></h3>
<p>Every document class needs an identifier. You designate the field
that serves as the identifier with the <code class="docutils literal"><span class="pre">&#64;Id</span></code> marker annotation.
Here is an 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="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
<span class="sd">/** @Document */</span>
<span class="k">class</span> <span class="nc">User</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="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\User&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;field</span> <span class="na">fieldName=</span><span class="s">&quot;id&quot;</span> <span class="na">id=</span><span class="s">&quot;true&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">Documents\User</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">fields</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">id</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">id</span>
<span class="l l-Scalar l-Scalar-Plain">id</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
</pre></div>
</div>
</li>
</ul>
</div>
<p>You can configure custom ID strategies if you don't want to use the default MongoId.
The available strategies are:</p>
<ul class="simple">
<li><code class="docutils literal"><span class="pre">AUTO</span></code> - Uses the native generated MongoId.</li>
<li><code class="docutils literal"><span class="pre">ALNUM</span></code> - Generates an alpha-numeric string (based on an incrementing value).</li>
<li><code class="docutils literal"><span class="pre">CUSTOM</span></code> - Defers generation to a AbstractIdGenerator implementation specified in the <code class="docutils literal"><span class="pre">class</span></code> option.</li>
<li><code class="docutils literal"><span class="pre">INCREMENT</span></code> - Uses another collection to auto increment an integer identifier.</li>
<li><code class="docutils literal"><span class="pre">UUID</span></code> - Generates a UUID identifier.</li>
<li><code class="docutils literal"><span class="pre">NONE</span></code> - Do not generate any identifier. ID must be manually set.</li>
</ul>
<p>Here is an example how to manually set a string identifier for your 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">MyPersistentClass</span>
<span class="p">{</span>
<span class="sd">/** @Id(strategy=&quot;NONE&quot;, type=&quot;string&quot;) */</span>
<span class="k">private</span> <span class="nv">$id</span><span class="p">;</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">setId</span><span class="p">(</span><span class="nv">$id</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">id</span> <span class="o">=</span> <span class="nv">$id</span><span class="p">;</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;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;MyPersistentClass&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;id&quot;</span> <span class="na">id=</span><span class="s">&quot;true&quot;</span> <span class="na">strategy=</span><span class="s">&quot;NONE&quot;</span> <span class="na">type=</span><span class="s">&quot;string&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">MyPersistentClass</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">fields</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">id</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">string</span>
<span class="l l-Scalar l-Scalar-Plain">id</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
<span class="l l-Scalar l-Scalar-Plain">strategy</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">NONE</span>
</pre></div>
</div>
</li>
</ul>
</div>
<p>When using the <code class="docutils literal"><span class="pre">NONE</span></code> strategy you will have to explicitly set an id before persisting the document:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="c1">//...</span>
<span class="nv">$document</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MyPersistentClass</span><span class="p">();</span>
<span class="nv">$document</span><span class="o">-&gt;</span><span class="na">setId</span><span class="p">(</span><span class="s1">&#39;my_unique_identifier&#39;</span><span class="p">);</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">persist</span><span class="p">(</span><span class="nv">$document</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>Now you can retrieve the document later:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="c1">//...</span>
<span class="nv">$document</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="s1">&#39;MyPersistentClass&#39;</span><span class="p">,</span> <span class="s1">&#39;my_unique_identifier&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>You can define your own ID generator by extending the
<code class="docutils literal"><span class="pre">Doctrine\ODM\MongoDB\Id\AbstractIdGenerator</span></code> class and specifying the class
as an option for the <code class="docutils literal"><span class="pre">CUSTOM</span></code> strategy:</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">MyPersistentClass</span>
<span class="p">{</span>
<span class="sd">/** @Id(strategy=&quot;CUSTOM&quot;, type=&quot;string&quot;, options={&quot;class&quot;=&quot;Vendor\Specific\Generator&quot;}) */</span>
<span class="k">private</span> <span class="nv">$id</span><span class="p">;</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">setId</span><span class="p">(</span><span class="nv">$id</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">id</span> <span class="o">=</span> <span class="nv">$id</span><span class="p">;</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;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;MyPersistentClass&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;id&quot;</span> <span class="na">id=</span><span class="s">&quot;true&quot;</span> <span class="na">strategy=</span><span class="s">&quot;CUSTOM&quot;</span> <span class="na">type=</span><span class="s">&quot;string&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;id-generator-option</span> <span class="na">name=</span><span class="s">&quot;class&quot;</span> <span class="na">value=</span><span class="s">&quot;Vendor\Specific\Generator&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/field&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">MyPersistentClass</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">fields</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">id</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">id</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
<span class="l l-Scalar l-Scalar-Plain">strategy</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">CUSTOM</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">string</span>
<span class="l l-Scalar l-Scalar-Plain">options</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">class</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">Vendor\Specific\Generator</span>
</pre></div>
</div>
</li>
</ul>
</div>
</div>
<div class="section" id="fields">
<h3>Fields<a class="headerlink" href="#fields" title="Permalink to this headline"></a></h3>
<p>To mark a property for document persistence the <code class="docutils literal"><span class="pre">&#64;Field</span></code> docblock
annotation can be used. This annotation usually requires at least 1
attribute to be set, the <code class="docutils literal"><span class="pre">type</span></code>. The <code class="docutils literal"><span class="pre">type</span></code> attribute specifies
the Doctrine Mapping Type to use for the field. If the type is not
specified, 'string' is used as the default mapping type since it is
the most flexible.</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="k">namespace</span> <span class="nx">Documents</span><span class="p">;</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">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">private</span> <span class="nv">$username</span><span class="p">;</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\User&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;field</span> <span class="na">fieldName=</span><span class="s">&quot;id&quot;</span> <span class="na">id=</span><span class="s">&quot;true&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;field</span> <span class="na">fieldName=</span><span class="s">&quot;username&quot;</span> <span class="na">type=</span><span class="s">&quot;string&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">Documents\User</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">fields</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">id</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">id</span>
<span class="l l-Scalar l-Scalar-Plain">id</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
<span class="l l-Scalar l-Scalar-Plain">username</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">string</span>
</pre></div>
</div>
</li>
</ul>
</div>
<p>In that example we mapped the property <code class="docutils literal"><span class="pre">id</span></code> to the field <code class="docutils literal"><span class="pre">id</span></code>
using the mapping type <code class="docutils literal"><span class="pre">id</span></code> and the property <code class="docutils literal"><span class="pre">name</span></code> is mapped
to the field <code class="docutils literal"><span class="pre">name</span></code> with the default mapping type <code class="docutils literal"><span class="pre">string</span></code>. As
you can see, by default the mongo field names are assumed to be the
same as the property names. To specify a different name for the
field, you can use the <code class="docutils literal"><span class="pre">name</span></code> attribute of the Field annotation
as follows:</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">/** @Field(name=&quot;db_name&quot;) */</span>
<span class="k">private</span> <span class="nv">$name</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;name&quot;</span> <span class="na">name=</span><span class="s">&quot;db_name&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">name</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">name</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">db_name</span>
</pre></div>
</div>
</li>
</ul>
</div>
</div>
</div>
<div class="section" id="custom-mapping-types">
<h2>Custom Mapping Types<a class="headerlink" href="#custom-mapping-types" title="Permalink to this headline"></a></h2>
<p>Doctrine allows you to create new mapping types. This can come in
handy when you're missing a specific mapping type or when you want
to replace the existing implementation of a mapping type.</p>
<p>In order to create a new mapping type you need to subclass
<code class="docutils literal"><span class="pre">Doctrine\ODM\MongoDB\Types\Type</span></code> and implement/override
the methods. Here is an example skeleton of such a custom type
class:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">namespace</span> <span class="nx">My\Project\Types</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\Types\Type</span><span class="p">;</span>
<span class="sd">/**</span>
<span class="sd"> * My custom datatype.</span>
<span class="sd"> */</span>
<span class="k">class</span> <span class="nc">MyType</span> <span class="k">extends</span> <span class="nx">Type</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">convertToPHPValue</span><span class="p">(</span><span class="nv">$value</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">// Note: this function is only called when your custom type is used</span>
<span class="c1">// as an identifier. For other cases, closureToPHP() will be called.</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">\DateTime</span><span class="p">(</span><span class="s1">&#39;@&#39;</span> <span class="o">.</span> <span class="nv">$value</span><span class="o">-&gt;</span><span class="na">sec</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">closureToPHP</span><span class="p">()</span>
<span class="p">{</span>
<span class="c1">// Return the string body of a PHP closure that will receive $value</span>
<span class="c1">// and store the result of a conversion in a $return variable</span>
<span class="k">return</span> <span class="s1">&#39;$return = new \DateTime($value);&#39;</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">convertToDatabaseValue</span><span class="p">(</span><span class="nv">$value</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">// This is called to convert a PHP value to its Mongo equivalent</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">\MongoDate</span><span class="p">(</span><span class="nv">$value</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Restrictions to keep in mind:</p>
<ul class="simple">
<li>If the value of the field is <em>NULL</em> the method
<code class="docutils literal"><span class="pre">convertToDatabaseValue()</span></code> is not called.</li>
<li>The <code class="docutils literal"><span class="pre">UnitOfWork</span></code> never passes values to the database convert
method that did not change in the request.</li>
</ul>
<p>When you have implemented the type you still need to let Doctrine
know about it. This can be achieved through the
<code class="docutils literal"><span class="pre">Doctrine\ODM\MongoDB\Types\Type#registerType($name,</span> <span class="pre">$class)</span></code>
method.</p>
<p>Here is an example:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="c1">// in bootstrapping code</span>
<span class="c1">// ...</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\Types\Type</span><span class="p">;</span>
<span class="c1">// ...</span>
<span class="c1">// Register my type</span>
<span class="nx">Type</span><span class="o">::</span><span class="na">addType</span><span class="p">(</span><span class="s1">&#39;mytype&#39;</span><span class="p">,</span> <span class="s1">&#39;My\Project\Types\MyType&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>As can be seen above, when registering the custom types in the
configuration you specify a unique name for the mapping type and
map that to the corresponding <a href="#id2"><span class="problematic" id="id3">|FQCN|</span></a>. Now you can use your new
type in your mapping like this:</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="k">class</span> <span class="nc">MyPersistentClass</span>
<span class="p">{</span>
<span class="sd">/** @Field(type=&quot;mytype&quot;) */</span>
<span class="k">private</span> <span class="nv">$field</span><span class="p">;</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;field&quot;</span> <span class="na">type=</span><span class="s">&quot;mytype&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">field</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">mytype</span>
</pre></div>
</div>
</li>
</ul>
</div>
</div>
<div class="section" id="multiple-document-types-in-a-collection">
<h2>Multiple Document Types in a Collection<a class="headerlink" href="#multiple-document-types-in-a-collection" title="Permalink to this headline"></a></h2>
<p>You can easily store multiple types of documents in a single collection. This
requires specifying the same collection name, <code class="docutils literal"><span class="pre">discriminatorField</span></code>, and
(optionally) <code class="docutils literal"><span class="pre">discriminatorMap</span></code> mapping options for each class that will share
the collection. Here is an example:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/**</span>
<span class="sd"> * @Document(collection=&quot;my_documents&quot;)</span>
<span class="sd"> * @DiscriminatorField(&quot;type&quot;)</span>
<span class="sd"> * @DiscriminatorMap({&quot;article&quot;=&quot;Article&quot;, &quot;album&quot;=&quot;Album&quot;})</span>
<span class="sd"> */</span>
<span class="k">class</span> <span class="nc">Article</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="p">}</span>
<span class="sd">/**</span>
<span class="sd"> * @Document(collection=&quot;my_documents&quot;)</span>
<span class="sd"> * @DiscriminatorField(&quot;type&quot;)</span>
<span class="sd"> * @DiscriminatorMap({&quot;article&quot;=&quot;Article&quot;, &quot;album&quot;=&quot;Album&quot;})</span>
<span class="sd"> */</span>
<span class="k">class</span> <span class="nc">Album</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</div>
<p>All instances of <code class="docutils literal"><span class="pre">Article</span></code> and <code class="docutils literal"><span class="pre">Album</span></code> will be stored in the
<code class="docutils literal"><span class="pre">my_documents</span></code> collection. You can query for the documents of a particular
class just like you normally would and the results will automatically be limited
based on the discriminator value for that class.</p>
<p>If you wish to query for multiple types of documents from the collection, you
may pass an array of document class names when creating a query builder:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$query</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQuery</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="s1">&#39;Article&#39;</span><span class="p">,</span> <span class="s1">&#39;Album&#39;</span><span class="p">));</span>
<span class="nv">$documents</span> <span class="o">=</span> <span class="nv">$query</span><span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
</pre></div>
</div>
<p>The above will return a cursor that will allow you to iterate over all
<code class="docutils literal"><span class="pre">Article</span></code> and <code class="docutils literal"><span class="pre">Album</span></code> documents in the collections.</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="#">Basic Mapping</a><ul>
<li><a class="reference internal" href="#mapping-drivers">Mapping Drivers</a></li>
<li><a class="reference internal" href="#introduction-to-docblock-annotations">Introduction to Docblock Annotations</a></li>
<li><a class="reference internal" href="#persistent-classes">Persistent classes</a></li>
<li><a class="reference internal" href="#doctrine-mapping-types">Doctrine Mapping Types</a></li>
<li><a class="reference internal" href="#property-mapping">Property Mapping</a><ul>
<li><a class="reference internal" href="#basic-mapping-identifiers">Identifiers</a></li>
<li><a class="reference internal" href="#fields">Fields</a></li>
</ul>
</li>
<li><a class="reference internal" href="#custom-mapping-types">Custom Mapping Types</a></li>
<li><a class="reference internal" href="#multiple-document-types-in-a-collection">Multiple Document Types in a Collection</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/basic-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>
@@ -0,0 +1,212 @@
<!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>Best Practices &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="best-practices">
<h1>Best Practices<a class="headerlink" href="#best-practices" title="Permalink to this headline"></a></h1>
<p>Here are some best practices you can follow when working with the Doctrine MongoDB ODM.</p>
<div class="section" id="constrain-relationships-as-much-as-possible">
<h2>Constrain relationships as much as possible<a class="headerlink" href="#constrain-relationships-as-much-as-possible" title="Permalink to this headline"></a></h2>
<p>It is important to constrain relationships as much as possible. This means:</p>
<ul class="simple">
<li>Impose a traversal direction (avoid bidirectional associations if possible)</li>
<li>Eliminate nonessential associations</li>
</ul>
<p>This has several benefits:</p>
<ul class="simple">
<li>Reduced coupling in your domain model</li>
<li>Simpler code in your domain model (no need to maintain bidirectionality properly)</li>
<li>Less work for Doctrine</li>
</ul>
</div>
<div class="section" id="use-events-judiciously">
<h2>Use events judiciously<a class="headerlink" href="#use-events-judiciously" title="Permalink to this headline"></a></h2>
<p>The event system of Doctrine is great and fast. Even though making
heavy use of events, especially lifecycle events, can have a
negative impact on the performance of your application. Thus you
should use events judiciously.</p>
</div>
<div class="section" id="use-cascades-judiciously">
<h2>Use cascades judiciously<a class="headerlink" href="#use-cascades-judiciously" title="Permalink to this headline"></a></h2>
<p>Automatic cascades of the persist/remove/merge/etc. operations are
very handy but should be used wisely. Do NOT simply add all
cascades to all associations. Think about which cascades actually
do make sense for you for a particular association, given the
scenarios it is most likely used in.</p>
</div>
<div class="section" id="don-t-use-special-characters">
<h2>Don't use special characters<a class="headerlink" href="#don-t-use-special-characters" title="Permalink to this headline"></a></h2>
<p>Avoid using any non-ASCII characters in class, field, table or
column names. Doctrine itself is not unicode-safe in many places
and will not be until PHP itself is fully unicode-aware.</p>
</div>
<div class="section" id="initialize-collections-in-the-constructor">
<h2>Initialize collections in the constructor<a class="headerlink" href="#initialize-collections-in-the-constructor" title="Permalink to this headline"></a></h2>
<p>It is recommended best practice to initialize any business
collections in documents in the constructor.</p>
<p>Example:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">namespace</span> <span class="nx">MyProject\Model</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Doctrine\Common\Collections\ArrayCollection</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">User</span>
<span class="p">{</span>
<span class="k">private</span> <span class="nv">$addresses</span><span class="p">;</span>
<span class="k">private</span> <span class="nv">$articles</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="nv">$this</span><span class="o">-&gt;</span><span class="na">articles</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="p">}</span>
</pre></div>
</div>
</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="#">Best Practices</a><ul>
<li><a class="reference internal" href="#constrain-relationships-as-much-as-possible">Constrain relationships as much as possible</a></li>
<li><a class="reference internal" href="#use-events-judiciously">Use events judiciously</a></li>
<li><a class="reference internal" href="#use-cascades-judiciously">Use cascades judiciously</a></li>
<li><a class="reference internal" href="#don-t-use-special-characters">Don't use special characters</a></li>
<li><a class="reference internal" href="#initialize-collections-in-the-constructor">Initialize collections in the constructor</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/best-practices.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>
@@ -0,0 +1,348 @@
<!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>Bi-Directional References &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="bi-directional-references">
<h1>Bi-Directional References<a class="headerlink" href="#bi-directional-references" title="Permalink to this headline"></a></h1>
<p>By default when you map a bi-directional reference, the reference is maintained on both sides
of the relationship and there is not a single &quot;owning side&quot;. Both sides are considered owning
and changes are tracked and persisted separately. Here is an example:</p>
<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">BlogPost</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="sd">/** @ReferenceOne(targetDocument=&quot;User&quot;) */</span>
<span class="k">private</span> <span class="nv">$user</span><span class="p">;</span>
<span class="p">}</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(targetDocument=&quot;BlogPost&quot;) */</span>
<span class="k">private</span> <span class="nv">$posts</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>When I persist some instances of the above classes the references would exist on both sides! The
<code class="docutils literal"><span class="pre">BlogPost</span></code> collection would have a <a class="reference external" href="https://docs.mongodb.com/manual/reference/database-references/#dbrefs">DBRef</a> stored on the <code class="docutils literal"><span class="pre">$user</span></code> property and the <code class="docutils literal"><span class="pre">User</span></code>
collection would have a <a class="reference external" href="https://docs.mongodb.com/manual/reference/database-references/#dbrefs">DBRef</a> stored in the <code class="docutils literal"><span class="pre">$posts</span></code> property.</p>
<div class="section" id="owning-and-inverse-sides">
<h2>Owning and Inverse Sides<a class="headerlink" href="#owning-and-inverse-sides" title="Permalink to this headline"></a></h2>
<p>A user may have lots of posts and we don't need to store a reference to each post on the user, we
can get the users post by running a query like the following:</p>
<div class="highlight-javascript"><div class="highlight"><pre><span class="nx">db</span><span class="p">.</span><span class="nx">BlogPost</span><span class="p">.</span><span class="nx">find</span><span class="p">({</span> <span class="s1">&#39;user.$id&#39;</span> <span class="o">:</span> <span class="nx">user</span><span class="p">.</span><span class="nx">id</span> <span class="p">})</span>
</pre></div>
</div>
<p>In order to map this you can use the <code class="docutils literal"><span class="pre">inversedBy</span></code> and <code class="docutils literal"><span class="pre">mappedBy</span></code> options. Here is the same
example above where we implement this:</p>
<div class="section" id="one-to-many">
<h3>One to Many<a class="headerlink" href="#one-to-many" title="Permalink to this headline"></a></h3>
<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">BlogPost</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="sd">/** @ReferenceOne(targetDocument=&quot;User&quot;, inversedBy=&quot;posts&quot;) */</span>
<span class="k">private</span> <span class="nv">$user</span><span class="p">;</span>
<span class="p">}</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(targetDocument=&quot;BlogPost&quot;, mappedBy=&quot;user&quot;) */</span>
<span class="k">private</span> <span class="nv">$posts</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>So now when we persist a <code class="docutils literal"><span class="pre">User</span></code> and multiple <code class="docutils literal"><span class="pre">BlogPost</span></code> instances for that <code class="docutils literal"><span class="pre">User</span></code>:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$user</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">User</span><span class="p">();</span>
<span class="nv">$post1</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">BlogPost</span><span class="p">();</span>
<span class="nv">$post1</span><span class="o">-&gt;</span><span class="na">setUser</span><span class="p">(</span><span class="nv">$user</span><span class="p">);</span>
<span class="nv">$post2</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">BlogPost</span><span class="p">();</span>
<span class="nv">$post2</span><span class="o">-&gt;</span><span class="na">setUser</span><span class="p">(</span><span class="nv">$user</span><span class="p">);</span>
<span class="nv">$post3</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">BlogPost</span><span class="p">();</span>
<span class="nv">$post3</span><span class="o">-&gt;</span><span class="na">setUser</span><span class="p">(</span><span class="nv">$user</span><span class="p">);</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">persist</span><span class="p">(</span><span class="nv">$post1</span><span class="p">);</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">persist</span><span class="p">(</span><span class="nv">$post2</span><span class="p">);</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">persist</span><span class="p">(</span><span class="nv">$post3</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>And we retrieve the <code class="docutils literal"><span class="pre">User</span></code> later to access the posts for that user:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$user</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="s1">&#39;User&#39;</span><span class="p">,</span> <span class="nv">$user</span><span class="o">-&gt;</span><span class="na">id</span><span class="p">);</span>
<span class="nv">$posts</span> <span class="o">=</span> <span class="nv">$user</span><span class="o">-&gt;</span><span class="na">getPosts</span><span class="p">();</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$posts</span> <span class="k">as</span> <span class="nv">$post</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The above will execute a query like the following to lazily load the collection of posts to
iterate over:</p>
<div class="highlight-javascript"><div class="highlight"><pre><span class="nx">db</span><span class="p">.</span><span class="nx">BlogPost</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span> <span class="p">{</span> <span class="s1">&#39;user.$id&#39;</span> <span class="o">:</span> <span class="nx">user</span><span class="p">.</span><span class="nx">id</span> <span class="p">}</span> <span class="p">)</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Remember that the inverse side, the side which specified <code class="docutils literal"><span class="pre">mappedBy</span></code> is immutable and
any changes to the state of the reference will not be persisted.</p>
</div>
</div>
</div>
<div class="section" id="other-examples">
<h2>Other Examples<a class="headerlink" href="#other-examples" title="Permalink to this headline"></a></h2>
<p>Here are several examples which implement the <code class="docutils literal"><span class="pre">inversedBy</span></code> and <code class="docutils literal"><span class="pre">mappedBy</span></code> options:</p>
<div class="section" id="one-to-one">
<h3>One to One<a class="headerlink" href="#one-to-one" title="Permalink to this headline"></a></h3>
<p>Here is an example where we have a one to one relationship between <code class="docutils literal"><span class="pre">Cart</span></code> and <code class="docutils literal"><span class="pre">Customer</span></code>:</p>
<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">Cart</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="sd">/**</span>
<span class="sd"> * @ReferenceOne(targetDocument=&quot;Customer&quot;, inversedBy=&quot;cart&quot;)</span>
<span class="sd"> */</span>
<span class="k">public</span> <span class="nv">$customer</span><span class="p">;</span>
<span class="p">}</span>
<span class="sd">/** @Document */</span>
<span class="k">class</span> <span class="nc">Customer</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="sd">/**</span>
<span class="sd"> * @ReferenceOne(targetDocument=&quot;Cart&quot;, mappedBy=&quot;customer&quot;)</span>
<span class="sd"> */</span>
<span class="k">public</span> <span class="nv">$cart</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The owning side is on <code class="docutils literal"><span class="pre">Cart.customer</span></code> and the <code class="docutils literal"><span class="pre">Customer.cart</span></code> referenced is loaded with a query
like this:</p>
<div class="highlight-javascript"><div class="highlight"><pre><span class="nx">db</span><span class="p">.</span><span class="nx">Cart</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span> <span class="p">{</span> <span class="s1">&#39;customer.$id&#39;</span> <span class="o">:</span> <span class="nx">customer</span><span class="p">.</span><span class="nx">id</span> <span class="p">}</span> <span class="p">)</span>
</pre></div>
</div>
<p>If you want to nullify the relationship between a <code class="docutils literal"><span class="pre">Cart</span></code> instance and <code class="docutils literal"><span class="pre">Customer</span></code> instance
you must null it out on the <code class="docutils literal"><span class="pre">Cart.customer</span></code> side:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$cart</span><span class="o">-&gt;</span><span class="na">setCustomer</span><span class="p">(</span><span class="k">null</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>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">When specifying inverse one-to-one relationships the referenced document is
loaded directly when the owning document is hydrated instead of using a
proxy. In the example above, loading a <code class="docutils literal"><span class="pre">Customer</span></code> object from the database
would also cause the corresponding <code class="docutils literal"><span class="pre">Cart</span></code> to be loaded. This can cause
performance issues when loading many <code class="docutils literal"><span class="pre">Customer</span></code> objects at once.</p>
</div>
</div>
<div class="section" id="self-referencing-many-to-many">
<h3>Self-Referencing Many to Many<a class="headerlink" href="#self-referencing-many-to-many" title="Permalink to this headline"></a></h3>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">namespace</span> <span class="nx">Documents</span><span class="p">;</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;User&quot;, mappedBy=&quot;myFriends&quot;)</span>
<span class="sd"> */</span>
<span class="k">public</span> <span class="nv">$friendsWithMe</span><span class="p">;</span>
<span class="sd">/**</span>
<span class="sd"> * @ReferenceMany(targetDocument=&quot;User&quot;, inversedBy=&quot;friendsWithMe&quot;)</span>
<span class="sd"> */</span>
<span class="k">public</span> <span class="nv">$myFriends</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="nv">$name</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">name</span> <span class="o">=</span> <span class="nv">$name</span><span class="p">;</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">friendsWithMe</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">\Doctrine\Common\Collections\ArrayCollection</span><span class="p">();</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">myFriends</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">\Doctrine\Common\Collections\ArrayCollection</span><span class="p">();</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">addFriend</span><span class="p">(</span><span class="nx">User</span> <span class="nv">$user</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$user</span><span class="o">-&gt;</span><span class="na">friendsWithMe</span><span class="p">[]</span> <span class="o">=</span> <span class="nv">$this</span><span class="p">;</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">myFriends</span><span class="p">[]</span> <span class="o">=</span> <span class="nv">$user</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
</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="#">Bi-Directional References</a><ul>
<li><a class="reference internal" href="#owning-and-inverse-sides">Owning and Inverse Sides</a><ul>
<li><a class="reference internal" href="#one-to-many">One to Many</a></li>
</ul>
</li>
<li><a class="reference internal" href="#other-examples">Other Examples</a><ul>
<li><a class="reference internal" href="#one-to-one">One to One</a></li>
<li><a class="reference internal" href="#self-referencing-many-to-many">Self-Referencing Many to Many</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/bidirectional-references.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>
@@ -0,0 +1,233 @@
<!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>Capped Collections &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="capped-collections">
<h1>Capped Collections<a class="headerlink" href="#capped-collections" title="Permalink to this headline"></a></h1>
<p>Capped collections are fixed sized collections that have a very
high performance auto-LRU age-out feature (age out is based on
insertion order).</p>
<p>In addition, capped collections automatically, with high
performance, maintain insertion order for the objects in the
collection; this is very powerful for certain use cases such as
logging.</p>
<div class="section" id="mapping">
<h2>Mapping<a class="headerlink" href="#mapping" title="Permalink to this headline"></a></h2>
<p>You can configure the collection in the <code class="docutils literal"><span class="pre">collection</span></code> attribute of
the <code class="docutils literal"><span class="pre">&#64;Document</span></code> annotation:</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"> * @Document(collection={</span>
<span class="sd"> * &quot;name&quot;=&quot;collname&quot;,</span>
<span class="sd"> * &quot;capped&quot;=true,</span>
<span class="sd"> * &quot;size&quot;=100000,</span>
<span class="sd"> * &quot;max&quot;=1000</span>
<span class="sd"> * })</span>
<span class="sd"> */</span>
<span class="k">class</span> <span class="nc">Category</span>
<span class="p">{</span>
<span class="sd">/** @Id */</span>
<span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">public</span> <span class="nv">$name</span><span class="p">;</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\Category&quot;</span> <span class="na">collection=</span><span class="s">&quot;collname&quot;</span> <span class="na">capped-collection=</span><span class="s">&quot;true&quot;</span> <span class="na">capped-collection-size=</span><span class="s">&quot;100000&quot;</span> <span class="na">capped-collection-max=</span><span class="s">&quot;1000&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;field</span> <span class="na">fieldName=</span><span class="s">&quot;id&quot;</span> <span class="na">id=</span><span class="s">&quot;true&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;field</span> <span class="na">fieldName=</span><span class="s">&quot;name&quot;</span> <span class="na">type=</span><span class="s">&quot;string&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">Documents\Category</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">collection</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">name</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">collname</span>
<span class="l l-Scalar l-Scalar-Plain">capped</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
<span class="l l-Scalar l-Scalar-Plain">size</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">100000</span>
<span class="l l-Scalar l-Scalar-Plain">max</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">1000</span>
<span class="l l-Scalar l-Scalar-Plain">fields</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">id</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">id</span>
<span class="l l-Scalar l-Scalar-Plain">id</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
<span class="l l-Scalar l-Scalar-Plain">name</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">string</span>
</pre></div>
</div>
</li>
</ul>
</div>
</div>
<div class="section" id="creating">
<h2>Creating<a class="headerlink" href="#creating" title="Permalink to this headline"></a></h2>
<p>Remember that you must manually create the collections. If you let
MongoDB create the collection lazily the first time it is selected,
it will not be created with the capped configuration. You can
create the collection for a document with the <code class="docutils literal"><span class="pre">SchemaManager</span></code>
that can be acquired from your <code class="docutils literal"><span class="pre">DocumentManager</span></code> instance:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$documentManager</span><span class="o">-&gt;</span><span class="na">getSchemaManager</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">createDocumentCollection</span><span class="p">(</span><span class="s1">&#39;Category&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>You can drop the collection too if it already exists:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$documentManager</span><span class="o">-&gt;</span><span class="na">getSchemaManager</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">dropDocumentCollection</span><span class="p">(</span><span class="s1">&#39;Category&#39;</span><span class="p">);</span>
</pre></div>
</div>
</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="#">Capped Collections</a><ul>
<li><a class="reference internal" href="#mapping">Mapping</a></li>
<li><a class="reference internal" href="#creating">Creating</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/capped-collections.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>
@@ -0,0 +1,280 @@
<!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>Change Tracking Policies &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="change-tracking-policies">
<span id="id1"></span><h1>Change Tracking Policies<a class="headerlink" href="#change-tracking-policies" title="Permalink to this headline"></a></h1>
<p>Change tracking is the process of determining what has changed in
managed documents since the last time they were synchronized with
the database.</p>
<p>Doctrine provides 3 different change tracking policies, each having
its particular advantages and disadvantages. The change tracking
policy can be defined on a per-class basis (or more precisely,
per-hierarchy).</p>
<div class="section" id="deferred-implicit">
<h2>Deferred Implicit<a class="headerlink" href="#deferred-implicit" title="Permalink to this headline"></a></h2>
<p>The deferred implicit policy is the default change tracking policy
and the most convenient one. With this policy, Doctrine detects the
changes by a property-by-property comparison at commit time and
also detects changes to documents or new documents that are
referenced by other managed documents. Although the most convenient policy,
it can have negative effects on performance if you are dealing with large units
of work. Since Doctrine can't know what has changed, it needs to check
all managed documents for changes every time you invoke DocumentManager#flush(),
making this operation rather costly.</p>
</div>
<div class="section" id="deferred-explicit">
<h2>Deferred Explicit<a class="headerlink" href="#deferred-explicit" title="Permalink to this headline"></a></h2>
<p>The deferred explicit policy is similar to the deferred implicit
policy in that it detects changes through a property-by-property
comparison at commit time. The difference is that only documents are
considered that have been explicitly marked for change detection
through a call to DocumentManager#persist(document) or through a save
cascade. All other documents are skipped. This policy therefore
gives improved performance for larger units of work while
sacrificing the behavior of &quot;automatic dirty checking&quot;.</p>
<p>Therefore, flush() operations are potentially cheaper with this
policy. The negative aspect this has is that if you have a rather
large application and you pass your objects through several layers
for processing purposes and business tasks you may need to track
yourself which documents have changed on the way so you can pass
them to DocumentManager#persist().</p>
<p>This policy can be configured as follows:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/**</span>
<span class="sd"> * @Document</span>
<span class="sd"> * @ChangeTrackingPolicy(&quot;DEFERRED_EXPLICIT&quot;)</span>
<span class="sd"> */</span>
<span class="k">class</span> <span class="nc">User</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="notify">
<h2>Notify<a class="headerlink" href="#notify" title="Permalink to this headline"></a></h2>
<p>This policy is based on the assumption that the documents notify
interested listeners of changes to their properties. For that
purpose, a class that wants to use this policy needs to implement
the <code class="docutils literal"><span class="pre">NotifyPropertyChanged</span></code> interface from the Doctrine
namespace. As a guideline, such an implementation can look as
follows:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">Doctrine\Common\NotifyPropertyChanged</span><span class="p">,</span>
<span class="nx">Doctrine\Common\PropertyChangedListener</span><span class="p">;</span>
<span class="sd">/**</span>
<span class="sd"> * @Document</span>
<span class="sd"> * @ChangeTrackingPolicy(&quot;NOTIFY&quot;)</span>
<span class="sd"> */</span>
<span class="k">class</span> <span class="nc">MyDocument</span> <span class="k">implements</span> <span class="nx">NotifyPropertyChanged</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="k">private</span> <span class="nv">$_listeners</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">addPropertyChangedListener</span><span class="p">(</span><span class="nx">PropertyChangedListener</span> <span class="nv">$listener</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_listeners</span><span class="p">[]</span> <span class="o">=</span> <span class="nv">$listener</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Then, in each property setter of this class or derived classes, you
need to notify all the <code class="docutils literal"><span class="pre">PropertyChangedListener</span></code> instances. As an
example we add a convenience method on <code class="docutils literal"><span class="pre">MyDocument</span></code> that shows this
behavior:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="c1">// ...</span>
<span class="k">class</span> <span class="nc">MyDocument</span> <span class="k">implements</span> <span class="nx">NotifyPropertyChanged</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="k">protected</span> <span class="k">function</span> <span class="nf">_onPropertyChanged</span><span class="p">(</span><span class="nv">$propName</span><span class="p">,</span> <span class="nv">$oldValue</span><span class="p">,</span> <span class="nv">$newValue</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_listeners</span><span class="p">)</span> <span class="p">{</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_listeners</span> <span class="k">as</span> <span class="nv">$listener</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$listener</span><span class="o">-&gt;</span><span class="na">propertyChanged</span><span class="p">(</span><span class="nv">$this</span><span class="p">,</span> <span class="nv">$propName</span><span class="p">,</span> <span class="nv">$oldValue</span><span class="p">,</span> <span class="nv">$newValue</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">setData</span><span class="p">(</span><span class="nv">$data</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$data</span> <span class="o">!=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">data</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_onPropertyChanged</span><span class="p">(</span><span class="s1">&#39;data&#39;</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">data</span><span class="p">,</span> <span class="nv">$data</span><span class="p">);</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">data</span> <span class="o">=</span> <span class="nv">$data</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>You have to invoke <code class="docutils literal"><span class="pre">_onPropertyChanged</span></code> inside every method that
changes the persistent state of <code class="docutils literal"><span class="pre">MyDocument</span></code>.</p>
<p>The check whether the new value is different from the old one is
not mandatory but recommended. That way you also have full control
over when you consider a property changed.</p>
<p>The negative point of this policy is obvious: You need implement an
interface and write some plumbing code. But also note that we tried
hard to keep this notification functionality abstract. Strictly
speaking, it has nothing to do with the persistence layer. You may
find that property notification events come in handy in many other
scenarios as well. As mentioned earlier, the <code class="docutils literal"><span class="pre">Doctrine\Common</span></code>
namespace is not that evil and consists solely of very small classes
and interfaces that have almost no external dependencies and that you can easily take with you should
you want to swap out the persistence layer. This change tracking policy
does not introduce a dependency on the Doctrine persistence
layer.</p>
<p>The positive point and main advantage of this policy is its
effectiveness. It has the best performance characteristics of the 3
policies with larger units of work and a flush() operation is very
cheap when nothing has changed.</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="#">Change Tracking Policies</a><ul>
<li><a class="reference internal" href="#deferred-implicit">Deferred Implicit</a></li>
<li><a class="reference internal" href="#deferred-explicit">Deferred Explicit</a></li>
<li><a class="reference internal" href="#notify">Notify</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/change-tracking-policies.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>
@@ -0,0 +1,283 @@
<!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>Complex References &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="complex-references">
<h1>Complex References<a class="headerlink" href="#complex-references" title="Permalink to this headline"></a></h1>
<p>Sometimes you may want to access related documents using custom criteria or from
the inverse side of a relationship.</p>
<p>You can create an <a class="reference external" href="http://en.wikipedia.org/wiki/Immutable">immutable</a> reference to one or many documents and specify
how that reference is to be loaded. The reference is immutable in that it is
defined only in the mapping, unlike a typical reference where a <a class="reference external" href="http://php.net/manual/en/class.mongodbref.php">MongoDBRef</a> or
identifier (see <a class="reference internal" href="reference-mapping.html#storing-references"><span class="std std-ref">Storing References</span></a>) is stored on the document itself.</p>
<p>The following options may be used for <a class="reference internal" href="reference-mapping.html#reference-one"><span class="std std-ref">one</span></a> and
<a class="reference internal" href="reference-mapping.html#reference-many"><span class="std std-ref">many</span></a> reference mappings:</p>
<blockquote>
<div><ul class="simple">
<li><code class="docutils literal"><span class="pre">criteria</span></code> - Query criteria to apply to the cursor.</li>
<li><code class="docutils literal"><span class="pre">repositoryMethod</span></code> - The repository method used to create the cursor.</li>
<li><code class="docutils literal"><span class="pre">sort</span></code> - Sort criteria for the cursor.</li>
<li><code class="docutils literal"><span class="pre">skip</span></code> - Skip offset to apply to the cursor.</li>
<li><code class="docutils literal"><span class="pre">limit</span></code> - Limit to apply to the cursor.</li>
</ul>
</div></blockquote>
<div class="section" id="basic-example">
<h2>Basic Example<a class="headerlink" href="#basic-example" title="Permalink to this headline"></a></h2>
<p>In the following example, <code class="docutils literal"><span class="pre">$comments</span></code> will refer to all Comments for the
BlogPost and <code class="docutils literal"><span class="pre">$last5Comments</span></code> will refer to only the last five Comments. The
<code class="docutils literal"><span class="pre">mappedBy</span></code> field is used to determine which Comment field should be used for
querying by the BlogPost's ID.</p>
<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">BlogPost</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="sd">/** @ReferenceMany(targetDocument=&quot;Comment&quot;, mappedBy=&quot;blogPost&quot;) */</span>
<span class="k">private</span> <span class="nv">$comments</span><span class="p">;</span>
<span class="sd">/**</span>
<span class="sd"> * @ReferenceMany(</span>
<span class="sd"> * targetDocument=&quot;Comment&quot;,</span>
<span class="sd"> * mappedBy=&quot;blogPost&quot;,</span>
<span class="sd"> * sort={&quot;date&quot;=&quot;desc&quot;},</span>
<span class="sd"> * limit=5</span>
<span class="sd"> * )</span>
<span class="sd"> */</span>
<span class="k">private</span> <span class="nv">$last5Comments</span><span class="p">;</span>
<span class="p">}</span>
<span class="sd">/** @Document */</span>
<span class="k">class</span> <span class="nc">Comment</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="sd">/** @ReferenceOne(targetDocument=&quot;BlogPost&quot;, inversedBy=&quot;comments&quot;) */</span>
<span class="k">private</span> <span class="nv">$blogPost</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>You can also use <code class="docutils literal"><span class="pre">mappedBy</span></code> for referencing a single document, as in the
following example:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/**</span>
<span class="sd"> * @ReferenceOne(</span>
<span class="sd"> * targetDocument=&quot;Comment&quot;,</span>
<span class="sd"> * mappedBy=&quot;blogPost&quot;,</span>
<span class="sd"> * sort={&quot;date&quot;=&quot;desc&quot;}</span>
<span class="sd"> * )</span>
<span class="sd"> */</span>
<span class="k">private</span> <span class="nv">$lastComment</span><span class="p">;</span>
</pre></div>
</div>
</div>
<div class="section" id="criteria-example">
<h2><code class="docutils literal"><span class="pre">criteria</span></code> Example<a class="headerlink" href="#criteria-example" title="Permalink to this headline"></a></h2>
<p>Use <code class="docutils literal"><span class="pre">criteria</span></code> to further match referenced documents. In the following
example, <code class="docutils literal"><span class="pre">$commentsByAdmin</span></code> will refer only comments created by
administrators:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/**</span>
<span class="sd"> * @ReferenceMany(</span>
<span class="sd"> * targetDocument=&quot;Comment&quot;,</span>
<span class="sd"> * mappedBy=&quot;blogPost&quot;,</span>
<span class="sd"> * criteria={&quot;isByAdmin&quot; : true}</span>
<span class="sd"> * )</span>
<span class="sd"> */</span>
<span class="k">private</span> <span class="nv">$commentsByAdmin</span><span class="p">;</span>
</pre></div>
</div>
</div>
<div class="section" id="repositorymethod-example">
<h2><code class="docutils literal"><span class="pre">repositoryMethod</span></code> Example<a class="headerlink" href="#repositorymethod-example" title="Permalink to this headline"></a></h2>
<p>Alternatively, you can use <code class="docutils literal"><span class="pre">repositoryMethod</span></code> to specify a custom method to
call on the Comment repository class to populate the reference.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/**</span>
<span class="sd"> * @ReferenceMany(</span>
<span class="sd"> * targetDocument=&quot;Comment&quot;,</span>
<span class="sd"> * mappedBy=&quot;blogPost&quot;,</span>
<span class="sd"> * repositoryMethod=&quot;findSomeComments&quot;</span>
<span class="sd"> * )</span>
<span class="sd"> */</span>
<span class="k">private</span> <span class="nv">$someComments</span><span class="p">;</span>
</pre></div>
</div>
<p>The <code class="docutils literal"><span class="pre">Comment</span></code> class will need to have a custom repository class configured:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/** @Document(repositoryClass=&quot;CommentRepository&quot;) */</span>
<span class="k">class</span> <span class="nc">Comment</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Lastly, the <code class="docutils literal"><span class="pre">CommentRepository</span></code> class will need a <code class="docutils literal"><span class="pre">findSomeComments()</span></code>
method which shall return <code class="docutils literal"><span class="pre">Doctrine\MongoDB\CursorInterface</span></code>. When this method
is called to populate the reference, Doctrine will provide the Blogpost instance
(i.e. owning document) as the first argument:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">class</span> <span class="nc">CommentRepository</span> <span class="k">extends</span> <span class="nx">\Doctrine\ODM\MongoDB\DocumentRepository</span>
<span class="p">{</span>
<span class="sd">/**</span>
<span class="sd"> * @return \Doctrine\ODM\MongoDB\Cursor</span>
<span class="sd"> */</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">findSomeComments</span><span class="p">(</span><span class="nx">BlogPost</span> <span class="nv">$blogPost</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;blogPost&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">references</span><span class="p">(</span><span class="nv">$blogPost</span><span class="p">);</span>
<span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</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="#">Complex References</a><ul>
<li><a class="reference internal" href="#basic-example">Basic Example</a></li>
<li><a class="reference internal" href="#criteria-example"><code class="docutils literal"><span class="pre">criteria</span></code> Example</a></li>
<li><a class="reference internal" href="#repositorymethod-example"><code class="docutils literal"><span class="pre">repositoryMethod</span></code> Example</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/complex-references.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>
@@ -0,0 +1,188 @@
<!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>Console Commands &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="console-commands">
<h1>Console Commands<a class="headerlink" href="#console-commands" title="Permalink to this headline"></a></h1>
<p>Doctrine MongoDB ODM offers some console commands, which utilize Symfony2's
Console component, to ease your development process:</p>
<ul class="simple">
<li><code class="docutils literal"><span class="pre">odm:clear-cache:metadata</span></code> - Clear all metadata cache of the various cache drivers.</li>
<li><code class="docutils literal"><span class="pre">odm:query</span></code> - Query mongodb and inspect the outputted results from your document classes.</li>
<li><code class="docutils literal"><span class="pre">odm:generate:documents</span></code> - Generate document classes and method stubs from your mapping information.</li>
<li><code class="docutils literal"><span class="pre">odm:generate:hydrators</span></code> - Generates hydrator classes for document classes.</li>
<li><code class="docutils literal"><span class="pre">odm:generate:proxies</span></code> - Generates proxy classes for document classes.</li>
<li><code class="docutils literal"><span class="pre">odm:generate:repositories</span></code> - Generate repository classes from your mapping information.</li>
<li><code class="docutils literal"><span class="pre">odm:schema:create</span></code> - Allows you to create databases, collections and indexes for your documents</li>
<li><code class="docutils literal"><span class="pre">odm:schema:drop</span></code> - Allows you to drop databases, collections and indexes for your documents</li>
<li><code class="docutils literal"><span class="pre">odm:schema:update</span></code> - Allows you to update indexes for your documents</li>
<li><code class="docutils literal"><span class="pre">odm:schema:shard</span></code> - Allows you to enable sharding for your documents</li>
</ul>
<p>Provided you have an existing <code class="docutils literal"><span class="pre">DocumentManager</span></code> instance, you can setup a
console command easily with the following code:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="c1">// mongodb.php</span>
<span class="c1">// ... include Composer autoloader and configure DocumentManager instance</span>
<span class="nv">$helperSet</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">\Symfony\Component\Console\Helper\HelperSet</span><span class="p">(</span><span class="k">array</span><span class="p">(</span>
<span class="s1">&#39;dm&#39;</span> <span class="o">=&gt;</span> <span class="k">new</span> <span class="nx">\Doctrine\ODM\MongoDB\Tools\Console\Helper\DocumentManagerHelper</span><span class="p">(</span><span class="nv">$dm</span><span class="p">),</span>
<span class="p">));</span>
<span class="nv">$app</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Application</span><span class="p">(</span><span class="s1">&#39;Doctrine MongoDB ODM&#39;</span><span class="p">);</span>
<span class="nv">$app</span><span class="o">-&gt;</span><span class="na">setHelperSet</span><span class="p">(</span><span class="nv">$helperSet</span><span class="p">);</span>
<span class="nv">$app</span><span class="o">-&gt;</span><span class="na">addCommands</span><span class="p">(</span><span class="k">array</span><span class="p">(</span>
<span class="k">new</span> <span class="nx">\Doctrine\ODM\MongoDB\Tools\Console\Command\GenerateDocumentsCommand</span><span class="p">(),</span>
<span class="k">new</span> <span class="nx">\Doctrine\ODM\MongoDB\Tools\Console\Command\GenerateHydratorsCommand</span><span class="p">(),</span>
<span class="k">new</span> <span class="nx">\Doctrine\ODM\MongoDB\Tools\Console\Command\GenerateProxiesCommand</span><span class="p">(),</span>
<span class="k">new</span> <span class="nx">\Doctrine\ODM\MongoDB\Tools\Console\Command\GenerateRepositoriesCommand</span><span class="p">(),</span>
<span class="k">new</span> <span class="nx">\Doctrine\ODM\MongoDB\Tools\Console\Command\QueryCommand</span><span class="p">(),</span>
<span class="k">new</span> <span class="nx">\Doctrine\ODM\MongoDB\Tools\Console\Command\ClearCache\MetadataCommand</span><span class="p">(),</span>
<span class="k">new</span> <span class="nx">\Doctrine\ODM\MongoDB\Tools\Console\Command\Schema\CreateCommand</span><span class="p">(),</span>
<span class="k">new</span> <span class="nx">\Doctrine\ODM\MongoDB\Tools\Console\Command\Schema\DropCommand</span><span class="p">(),</span>
<span class="k">new</span> <span class="nx">\Doctrine\ODM\MongoDB\Tools\Console\Command\Schema\UpdateCommand</span><span class="p">(),</span>
<span class="k">new</span> <span class="nx">\Doctrine\ODM\MongoDB\Tools\Console\Command\Schema\ShardCommand</span><span class="p">(),</span>
<span class="p">));</span>
<span class="nv">$app</span><span class="o">-&gt;</span><span class="na">run</span><span class="p">();</span>
</pre></div>
</div>
<p>A reference implementation of the console command may be found in the
<code class="docutils literal"><span class="pre">tools/sandbox</span></code> directory of the project repository. That command is
configured to store generated hydrators and proxies in the same directory, and
relies on the main project's Composer dependencies. You will want to customize
its configuration files if you intend to use it in your own project.</p>
</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>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/console-commands.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>
@@ -0,0 +1,303 @@
<!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>Custom Collections &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="custom-collections">
<span id="custom-collection"></span><h1>Custom Collections<a class="headerlink" href="#custom-collections" title="Permalink to this headline"></a></h1>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">This feature was introduced in version 1.1</p>
</div>
<p>By default, Doctrine uses <code class="docutils literal"><span class="pre">ArrayCollection</span></code> implementation of its <code class="docutils literal"><span class="pre">Collection</span></code>
interface to hold both embedded and referenced documents. That collection may then
be wrapped by a <code class="docutils literal"><span class="pre">PersistentCollection</span></code> to allow for change tracking and other
persistence-related features.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">Doctrine\Common\Collections\ArrayCollection</span><span class="p">;</span>
<span class="sd">/** @Document */</span>
<span class="k">class</span> <span class="nc">Application</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="sd">/**</span>
<span class="sd"> * @EmbedMany(targetDocument=&quot;Section&quot;)</span>
<span class="sd"> */</span>
<span class="k">private</span> <span class="nv">$sections</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">sections</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="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</div>
<p>For most cases this solution is sufficient but more sophisticated domains could use
their own collections (e.g. a collection that ensures its contained objects are sorted)
or to simply add common filtering methods that otherwise would otherwise be added to
owning document's class.</p>
<div class="section" id="custom-collection-classes">
<h2>Custom Collection Classes<a class="headerlink" href="#custom-collection-classes" title="Permalink to this headline"></a></h2>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">You may want to check <a class="reference external" href="https://github.com/malarzm/collections">malarzm/collections</a>
which provides alternative implementations of Doctrine's <code class="docutils literal"><span class="pre">Collection</span></code> interface and
aims to kickstart development of your own collections.</p>
</div>
<p>Using your own <code class="docutils literal"><span class="pre">Collection</span></code> implementation is as simple as specifying the
<code class="docutils literal"><span class="pre">collectionClass</span></code> parameter in the <code class="docutils literal"><span class="pre">&#64;EmbedMany</span></code> or <code class="docutils literal"><span class="pre">&#64;ReferenceMany</span></code> mapping
and ensuring that your custom class is initialized in the owning class' constructor:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">Doctrine\Common\Collections\ArrayCollection</span><span class="p">;</span>
<span class="sd">/** @Document */</span>
<span class="k">class</span> <span class="nc">Application</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="sd">/**</span>
<span class="sd"> * @EmbedMany(</span>
<span class="sd"> * collectionClass=&quot;SectionCollection&quot;</span>
<span class="sd"> * targetDocument=&quot;Section&quot;</span>
<span class="sd"> * )</span>
<span class="sd"> */</span>
<span class="k">private</span> <span class="nv">$sections</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">sections</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">SectionCollection</span><span class="p">();</span>
<span class="p">}</span>
<span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</div>
<p>If you are satisfied with <code class="docutils literal"><span class="pre">ArrayCollection</span></code> and only want
to sprinkle it with some filtering methods, you may just extend it:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">Doctrine\Common\Collections\ArrayCollection</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">SectionCollection</span> <span class="k">extends</span> <span class="nx">ArrayCollection</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">getEnabled</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">filter</span><span class="p">(</span><span class="k">function</span><span class="p">(</span><span class="nx">Section</span> <span class="nv">$s</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="nv">$s</span><span class="o">-&gt;</span><span class="na">isEnabled</span><span class="p">();</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Alternatively, you may want to implement the whole class from scratch:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">Doctrine\Common\Collections\Collection</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">SectionCollection</span> <span class="k">implements</span> <span class="nx">Collection</span>
<span class="p">{</span>
<span class="k">private</span> <span class="nv">$elements</span> <span class="o">=</span> <span class="k">array</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="k">array</span> <span class="nv">$elements</span> <span class="o">=</span> <span class="k">array</span><span class="p">())</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">elements</span> <span class="o">=</span> <span class="nv">$elements</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// your implementation of all methods interface requires</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="taking-control-of-the-collection-s-constructor">
<h2>Taking Control of the Collection's Constructor<a class="headerlink" href="#taking-control-of-the-collection-s-constructor" title="Permalink to this headline"></a></h2>
<p>By default, Doctrine assumes that it can instantiate your collections in same
manner as an <code class="docutils literal"><span class="pre">ArrayCollection</span></code> (i.e. the only parameter is an optional PHP
array); however, you may want to inject additional dependencies into your
custom collection class(es). This will require you to create a
<a class="reference external" href="https://github.com/doctrine/mongodb-odm/blob/master/lib/Doctrine/ODM/MongoDB/PersistentCollection/PersistentCollectionFactory.php">PersistentCollectionFactory implementation</a>,
which Doctrine will then use to construct its persistent collections.
You may decide to implement this class from scratch or extend our
<code class="docutils literal"><span class="pre">AbstractPersistentCollectionFactory</span></code>:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\PersistentCollection\AbstractPersistentCollectionFactory</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Symfony\Component\EventDispatcher\EventDispatcherInterface</span><span class="p">;</span>
<span class="k">final</span> <span class="k">class</span> <span class="nc">YourPersistentCollectionFactory</span> <span class="k">extends</span> <span class="nx">AbstractPersistentCollectionFactory</span>
<span class="p">{</span>
<span class="k">private</span> <span class="nv">$eventDispatcher</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="nx">EventDispatcherInterface</span> <span class="nv">$eventDispatcher</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">eventDispatcher</span> <span class="o">=</span> <span class="nv">$eventDispatcher</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">protected</span> <span class="k">function</span> <span class="nf">createCollectionClass</span><span class="p">(</span><span class="nv">$collectionClass</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">switch</span> <span class="p">(</span><span class="nv">$collectionClass</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="nx">SectionCollection</span><span class="o">::</span><span class="na">class</span><span class="o">:</span>
<span class="k">return</span> <span class="k">new</span> <span class="nv">$collectionClass</span><span class="p">(</span><span class="k">array</span><span class="p">(),</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">eventDispatcher</span><span class="p">);</span>
<span class="k">default</span><span class="o">:</span>
<span class="k">return</span> <span class="k">new</span> <span class="nv">$collectionClass</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The factory class must then be registered in the <code class="docutils literal"><span class="pre">Configuration</span></code>:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$eventDispatcher</span> <span class="o">=</span> <span class="nv">$container</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s1">&#39;event_dispatcher&#39;</span><span class="p">);</span>
<span class="nv">$collFactory</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">YourPersistentCollectionFactory</span><span class="p">(</span><span class="nv">$eventDispatcher</span><span class="p">);</span>
<span class="nv">$configuration</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Configuration</span><span class="p">();</span>
<span class="c1">// your other config here</span>
<span class="nv">$configuration</span><span class="o">-&gt;</span><span class="na">setPersistentCollectionFactory</span><span class="p">(</span><span class="nv">$collFactory</span><span class="p">);</span>
</pre></div>
</div>
</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="#">Custom Collections</a><ul>
<li><a class="reference internal" href="#custom-collection-classes">Custom Collection Classes</a></li>
<li><a class="reference internal" href="#taking-control-of-the-collection-s-constructor">Taking Control of the Collection's Constructor</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/custom-collections.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>
@@ -0,0 +1,337 @@
<!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>Document Repositories &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="document-repositories">
<span id="id1"></span><h1>Document Repositories<a class="headerlink" href="#document-repositories" title="Permalink to this headline"></a></h1>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">A repository mediates between the domain and data mapping layers using a
collection-like interface for accessing domain objects.</p>
</div>
<p>In Doctrine, a repository is a class that concentrates code responsible for
querying and filtering your documents. ODM provides you with a default
<code class="docutils literal"><span class="pre">DocumentRepository</span></code> for all of your documents:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="cm">/* @var $repository \Doctrine\ODM\MongoDB\DocumentRepository */</span>
<span class="nv">$repository</span> <span class="o">=</span> <span class="nv">$documentManager</span><span class="o">-&gt;</span><span class="na">getRepository</span><span class="p">(</span><span class="nx">User</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$disabledUsers</span> <span class="o">=</span> <span class="nv">$repository</span><span class="o">-&gt;</span><span class="na">findBy</span><span class="p">([</span><span class="s1">&#39;disabled&#39;</span> <span class="o">=&gt;</span> <span class="k">true</span><span class="p">,</span> <span class="s1">&#39;activated&#39;</span> <span class="o">=&gt;</span> <span class="k">true</span><span class="p">]);</span>
</pre></div>
</div>
<p>The array passed to <code class="docutils literal"><span class="pre">findBy</span></code> specifies the criteria for which documents are matched.
ODM will assist with converting PHP values to equivalent BSON types whenever possible:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$group</span> <span class="o">=</span> <span class="nv">$documentManager</span><span class="o">-&gt;</span><span class="na">find</span><span class="p">(</span><span class="nx">Group</span><span class="o">::</span><span class="na">class</span><span class="p">,</span> <span class="mi">123</span><span class="p">);</span>
<span class="cm">/* @var $repository \Doctrine\ODM\MongoDB\DocumentRepository */</span>
<span class="nv">$repository</span> <span class="o">=</span> <span class="nv">$documentManager</span><span class="o">-&gt;</span><span class="na">getRepository</span><span class="p">(</span><span class="nx">User</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$usersInGroup</span> <span class="o">=</span> <span class="nv">$repository</span><span class="o">-&gt;</span><span class="na">findBy</span><span class="p">([</span><span class="s1">&#39;group&#39;</span> <span class="o">=&gt;</span> <span class="nv">$group</span><span class="p">]);</span>
</pre></div>
</div>
<p>The default repository implementation provides the following methods:</p>
<ul class="simple">
<li><code class="docutils literal"><span class="pre">find()</span></code> - finds one document by its identifier. This may skip a database query</li>
</ul>
<p>if the document is already managed by ODM.
- <code class="docutils literal"><span class="pre">findAll()</span></code> - finds all documents in the collection.
- <code class="docutils literal"><span class="pre">findBy()</span></code> - finds all documents matching the given criteria. Additional query
options may be specified (e.g. sort, limit, skip).
- <code class="docutils literal"><span class="pre">findOneBy()</span></code> - finds one document matching the given criteria.
- <code class="docutils literal"><span class="pre">matching()</span></code> - Finds all documents matching the given criteria, as expressed
with Doctrine's Criteria API.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">All above methods will include additional criteria specified by <a class="reference internal" href="filters.html#filters"><span class="std std-ref">Filters</span></a>.</p>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Magic <code class="docutils literal"><span class="pre">findBy</span></code> and <code class="docutils literal"><span class="pre">findOneBy</span></code> calls described below are deprecated in 1.2 and
will be removed in 2.0.</p>
</div>
<p>Additional methods that are not defined explicitly in the repository class may also be
used if they follow a specific naming convention:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$group</span> <span class="o">=</span> <span class="nv">$documentManager</span><span class="o">-&gt;</span><span class="na">find</span><span class="p">(</span><span class="nx">Group</span><span class="o">::</span><span class="na">class</span><span class="p">,</span> <span class="mi">123</span><span class="p">);</span>
<span class="cm">/* @var $repository \Doctrine\ODM\MongoDB\DocumentRepository */</span>
<span class="nv">$repository</span> <span class="o">=</span> <span class="nv">$documentManager</span><span class="o">-&gt;</span><span class="na">getRepository</span><span class="p">(</span><span class="nx">User</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$usersInGroup</span> <span class="o">=</span> <span class="nv">$repository</span><span class="o">-&gt;</span><span class="na">findByGroup</span><span class="p">(</span><span class="nv">$group</span><span class="p">);</span>
<span class="nv">$randomUser</span> <span class="o">=</span> <span class="nv">$repository</span><span class="o">-&gt;</span><span class="na">findOneByStatus</span><span class="p">(</span><span class="s1">&#39;active&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>In the above example, <code class="docutils literal"><span class="pre">findByGroup()</span></code> and <code class="docutils literal"><span class="pre">findOneByStatus()</span></code> will be handled by
the <code class="docutils literal"><span class="pre">__call</span></code> method, which intercepts calls to undefined methods. If the invoked
method's name starts with &quot;findBy&quot; or &quot;findOneBy&quot;, ODM will attempt to infer mapped
properties from the remainder of the method name (&quot;Group&quot; or &quot;Status&quot; as per example).
The above calls are equivalent to:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$group</span> <span class="o">=</span> <span class="nv">$documentManager</span><span class="o">-&gt;</span><span class="na">find</span><span class="p">(</span><span class="nx">Group</span><span class="o">::</span><span class="na">class</span><span class="p">,</span> <span class="mi">123</span><span class="p">);</span>
<span class="cm">/* @var $repository \Doctrine\ODM\MongoDB\DocumentRepository */</span>
<span class="nv">$repository</span> <span class="o">=</span> <span class="nv">$documentManager</span><span class="o">-&gt;</span><span class="na">getRepository</span><span class="p">(</span><span class="nx">User</span><span class="o">::</span><span class="na">class</span><span class="p">);</span>
<span class="nv">$usersInGroup</span> <span class="o">=</span> <span class="nv">$repository</span><span class="o">-&gt;</span><span class="na">findBy</span><span class="p">([</span><span class="s1">&#39;group&#39;</span> <span class="o">=&gt;</span> <span class="nv">$group</span><span class="p">]);</span>
<span class="nv">$randomUser</span> <span class="o">=</span> <span class="nv">$repository</span><span class="o">-&gt;</span><span class="na">findOneBy</span><span class="p">([</span><span class="s1">&#39;status&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;active&#39;</span><span class="p">]);</span>
</pre></div>
</div>
<div class="section" id="custom-repositories">
<h2>Custom Repositories<a class="headerlink" href="#custom-repositories" title="Permalink to this headline"></a></h2>
<p>A custom repository allows filtering logic to be consolidated into a single class instead
of spreading it throughout a project. A custom repository class may be specified for a
document class like so:</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="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
<span class="sd">/** @Document(repositoryClass=&quot;Repositories\UserRepository&quot;) */</span>
<span class="k">class</span> <span class="nc">User</span>
<span class="p">{</span>
<span class="cm">/* ... */</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;document</span> <span class="na">name=</span><span class="s">&quot;Documents\User&quot;</span> <span class="na">repository-class=</span><span class="s">&quot;Repositories\UserRepository&quot;</span><span class="nt">&gt;</span>
<span class="c">&lt;!-- ... --&gt;</span>
<span class="nt">&lt;/document&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">Documents\User</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">repositoryClass</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">Repositories\\UserRepository</span>
<span class="l l-Scalar l-Scalar-Plain">collection</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">user</span>
<span class="c1"># ...</span>
</pre></div>
</div>
</li>
</ul>
</div>
<p>The next step is implementing your repository class. In most cases, ODM's default
<code class="docutils literal"><span class="pre">DocumentRepository</span></code> class may be extended with additional methods that you need.
More complex cases that require passing additional dependencies to a custom repository
class will be discussed in the next section.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">namespace</span> <span class="nx">Repositories</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">UserRepository</span> <span class="k">extends</span> <span class="nx">DocumentRepository</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">findDisabled</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">findBy</span><span class="p">([</span><span class="s1">&#39;disabled&#39;</span> <span class="o">=&gt;</span> <span class="k">true</span><span class="p">,</span> <span class="s1">&#39;activated&#39;</span> <span class="o">=&gt;</span> <span class="k">true</span><span class="p">]);</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>It is also possible to change ODM's default <code class="docutils literal"><span class="pre">DocumentRepository</span></code> to your own
implementation for all documents (unless overridden by the mapping):</p>
<div class="highlight-php"><div class="highlight"><pre><span class="x">$documentManager-&gt;getConfiguration()</span>
<span class="x"> -&gt;setDefaultRepositoryClassName(MyDefaultRepository::class);</span>
</pre></div>
</div>
</div>
<div class="section" id="repositories-with-additional-dependencies">
<h2>Repositories with Additional Dependencies<a class="headerlink" href="#repositories-with-additional-dependencies" title="Permalink to this headline"></a></h2>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Implementing your own RepositoryFactory is possible since version 1.0, but the
<code class="docutils literal"><span class="pre">AbstractRepositoryFactory</span></code> class used in this example is only available since 1.2.</p>
</div>
<p>By default, Doctrine assumes that it can instantiate your repositories in same manner
as its default one:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">namespace</span> <span class="nx">Repositories</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">UserRepository</span> <span class="k">extends</span> <span class="nx">DocumentRepository</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="nx">DocumentManager</span> <span class="nv">$dm</span><span class="p">,</span> <span class="nx">UnitOfWork</span> <span class="nv">$uow</span><span class="p">,</span> <span class="nx">ClassMetadata</span> <span class="nv">$classMetadata</span><span class="p">)</span>
<span class="p">{</span>
<span class="cm">/* constructor is inherited from DocumentRepository */</span>
<span class="cm">/* ... */</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>In order to change the way Doctrine instantiates repositories, you will need to implement your own
<a class="reference external" href="https://github.com/doctrine/mongodb-odm/blob/master/lib/Doctrine/ODM/MongoDB/Repository/RepositoryFactory.php">RepositoryFactory</a></p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\Repository\AbstractRepositoryFactory</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Symfony\Component\EventDispatcher\EventDispatcherInterface</span><span class="p">;</span>
<span class="k">final</span> <span class="k">class</span> <span class="nc">YourRepositoryFactory</span> <span class="k">extends</span> <span class="nx">AbstractRepositoryFactory</span>
<span class="p">{</span>
<span class="k">private</span> <span class="nv">$eventDispatcher</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="nx">EventDispatcherInterface</span> <span class="nv">$eventDispatcher</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">eventDispatcher</span> <span class="o">=</span> <span class="nv">$eventDispatcher</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">protected</span> <span class="k">function</span> <span class="nf">instantiateRepository</span><span class="p">(</span><span class="nv">$repositoryClassName</span><span class="p">,</span> <span class="nx">DocumentManager</span> <span class="nv">$documentManager</span><span class="p">,</span> <span class="nx">ClassMetadata</span> <span class="nv">$metadata</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">switch</span> <span class="p">(</span><span class="nv">$repositoryClassName</span><span class="p">)</span> <span class="p">{</span>
<span class="k">case</span> <span class="nx">UserRepository</span><span class="o">::</span><span class="na">class</span><span class="o">:</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">UserRepository</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">eventDispatcher</span><span class="p">,</span> <span class="nv">$documentManager</span><span class="p">,</span> <span class="nv">$metadata</span><span class="p">);</span>
<span class="k">default</span><span class="o">:</span>
<span class="k">return</span> <span class="k">new</span> <span class="nv">$repositoryClassName</span><span class="p">(</span><span class="nv">$documentManager</span><span class="p">,</span> <span class="nv">$documentManager</span><span class="o">-&gt;</span><span class="na">getUnitOfWork</span><span class="p">(),</span> <span class="nv">$metadata</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The factory class must then be registered in the <code class="docutils literal"><span class="pre">Configuration</span></code>:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$eventDispatcher</span> <span class="o">=</span> <span class="nv">$container</span><span class="o">-&gt;</span><span class="na">get</span><span class="p">(</span><span class="s1">&#39;event_dispatcher&#39;</span><span class="p">);</span>
<span class="nv">$repoFactory</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">YourRepositoryFactory</span><span class="p">(</span><span class="nv">$eventDispatcher</span><span class="p">);</span>
<span class="nv">$configuration</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Configuration</span><span class="p">();</span>
<span class="c1">// your other config here</span>
<span class="nv">$configuration</span><span class="o">-&gt;</span><span class="na">setRepositoryFactory</span><span class="p">(</span><span class="nv">$repoFactory</span><span class="p">);</span>
</pre></div>
</div>
</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="#">Document Repositories</a><ul>
<li><a class="reference internal" href="#custom-repositories">Custom Repositories</a></li>
<li><a class="reference internal" href="#repositories-with-additional-dependencies">Repositories with Additional Dependencies</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/document-repositories.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>
@@ -0,0 +1,174 @@
<!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>Eager Cursors &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="eager-cursors">
<h1>Eager Cursors<a class="headerlink" href="#eager-cursors" title="Permalink to this headline"></a></h1>
<p>With a typical MongoDB cursor, it stays open during iteration and fetches
batches of documents as you iterate over the cursor. This isn't bad,
but sometimes you want to fetch all of the data eagerly. For example
when dealing with web applications, and you want to only show 50
documents from a collection you should fetch all the data in your
controller first before going on to the view.</p>
<p>Benefits:</p>
<ul class="simple">
<li>The cursor stays open for a much shorter period of time.</li>
<li>Data retrieval and hydration are consolidated operations.</li>
<li>Doctrine has the ability to retry the cursor when exceptions during interaction with mongodb are encountered.</li>
</ul>
<p>Example:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$qb</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;User&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">eagerCursor</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>
<span class="nv">$query</span> <span class="o">=</span> <span class="nv">$qb</span><span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">();</span>
<span class="nv">$users</span> <span class="o">=</span> <span class="nv">$query</span><span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span> <span class="c1">// returns instance of Doctrine\MongoDB\ODM\EagerCursor</span>
</pre></div>
</div>
<p>At this point all data is loaded from the database and cursors to MongoDB
have been closed but hydration of the data in to objects has not begun. Once
insertion starts the data will be hydrated in to PHP objects.</p>
<p>Example:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$users</span> <span class="k">as</span> <span class="nv">$user</span><span class="p">)</span> <span class="p">{</span>
<span class="k">echo</span> <span class="nv">$user</span><span class="o">-&gt;</span><span class="na">getUsername</span><span class="p">()</span><span class="o">.</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Not all documents are converted to objects at once, the hydration is still done
one document at a time during iteration. The only change is that all data is retrieved
first.</p>
</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>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/eager-cursors.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>
@@ -0,0 +1,426 @@
<!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>Embedded 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="embedded-mapping">
<h1>Embedded Mapping<a class="headerlink" href="#embedded-mapping" title="Permalink to this headline"></a></h1>
<p>This chapter explains how embedded documents are mapped in
Doctrine.</p>
<div class="section" id="embed-one">
<span id="id1"></span><h2>Embed One<a class="headerlink" href="#embed-one" title="Permalink to this headline"></a></h2>
<p>Embed a single 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">User</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="sd">/** @EmbedOne(targetDocument=&quot;Address&quot;) */</span>
<span class="k">private</span> <span class="nv">$address</span><span class="p">;</span>
<span class="c1">// ...</span>
<span class="p">}</span>
<span class="sd">/** @EmbeddedDocument */</span>
<span class="k">class</span> <span class="nc">Address</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\User&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;embed-one</span> <span class="na">field=</span><span class="s">&quot;address&quot;</span> <span class="na">target-document=</span><span class="s">&quot;Address&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">embedOne</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">address</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">Address</span>
<span class="l l-Scalar l-Scalar-Plain">Address</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">embeddedDocument</span>
</pre></div>
</div>
</li>
</ul>
</div>
</div>
<div class="section" id="embed-many">
<span id="id2"></span><h2>Embed Many<a class="headerlink" href="#embed-many" title="Permalink to this headline"></a></h2>
<p>Embed 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">/** @EmbedMany(targetDocument=&quot;Phonenumber&quot;) */</span>
<span class="k">private</span> <span class="nv">$phonenumbers</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">/** @EmbeddedDocument */</span>
<span class="k">class</span> <span class="nc">Phonenumber</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\User&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;embed-many</span> <span class="na">field=</span><span class="s">&quot;phonenumbers&quot;</span> <span class="na">target-document=</span><span class="s">&quot;Phonenumber&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">embedMany</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">phonenumbers</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">Phonenumber</span>
<span class="l l-Scalar l-Scalar-Plain">Phonenumber</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">embeddedDocument</span>
</pre></div>
</div>
</li>
</ul>
</div>
</div>
<div class="section" id="mixing-document-types">
<span id="embed-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 embedded documents in the same field,
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">/** @EmbedMany */</span>
<span class="k">private</span> <span class="nv">$tasks</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;embed-many</span> <span class="na">field=</span><span class="s">&quot;tasks&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">embedMany</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">tasks</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">$tasks</span></code> property can store 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 embedded document. The field name can be customized with 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"> * @EmbedMany(discriminatorField=&quot;type&quot;)</span>
<span class="sd"> */</span>
<span class="k">private</span> <span class="nv">$tasks</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;embed-many</span> <span class="na">field=</span><span class="s">&quot;tasks&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;/embed-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">embedMany</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">tasks</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="#id3"><span class="problematic" id="id4">|FQCN|</span></a>
in each embedded 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">User</span>
<span class="p">{</span>
<span class="c1">// ..</span>
<span class="sd">/**</span>
<span class="sd"> * @EmbedMany(</span>
<span class="sd"> * discriminatorMap={</span>
<span class="sd"> * &quot;download&quot;=&quot;DownloadTask&quot;,</span>
<span class="sd"> * &quot;build&quot;=&quot;BuildTask&quot;</span>
<span class="sd"> * }</span>
<span class="sd"> * )</span>
<span class="sd"> */</span>
<span class="k">private</span> <span class="nv">$tasks</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;embed-many</span> <span class="na">field=</span><span class="s">&quot;tasks&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;download&quot;</span> <span class="na">class=</span><span class="s">&quot;DownloadTask&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;discriminator-mapping</span> <span class="na">value=</span><span class="s">&quot;build&quot;</span> <span class="na">class=</span><span class="s">&quot;BuildTask&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/discriminator-map&gt;</span>
<span class="nt">&lt;/embed-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">embedMany</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">tasks</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">download</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">DownloadTask</span>
<span class="l l-Scalar l-Scalar-Plain">build</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">BuildTask</span>
</pre></div>
</div>
</li>
</ul>
</div>
<p>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:</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"> * @EmbedMany(</span>
<span class="sd"> * discriminatorMap={</span>
<span class="sd"> * &quot;download&quot;=&quot;DownloadTask&quot;,</span>
<span class="sd"> * &quot;build&quot;=&quot;BuildTask&quot;</span>
<span class="sd"> * },</span>
<span class="sd"> * defaultDiscriminatorValue=&quot;download&quot;</span>
<span class="sd"> * )</span>
<span class="sd"> */</span>
<span class="k">private</span> <span class="nv">$tasks</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;embed-many</span> <span class="na">field=</span><span class="s">&quot;tasks&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;download&quot;</span> <span class="na">class=</span><span class="s">&quot;DownloadTask&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;discriminator-mapping</span> <span class="na">value=</span><span class="s">&quot;build&quot;</span> <span class="na">class=</span><span class="s">&quot;BuildTask&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;download&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/embed-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">embedMany</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">tasks</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">download</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">DownloadTask</span>
<span class="l l-Scalar l-Scalar-Plain">build</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">BuildTask</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">download</span>
</pre></div>
</div>
</li>
</ul>
</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>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.</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="#">Embedded Mapping</a><ul>
<li><a class="reference internal" href="#embed-one">Embed One</a></li>
<li><a class="reference internal" href="#embed-many">Embed Many</a></li>
<li><a class="reference internal" href="#mixing-document-types">Mixing Document Types</a></li>
<li><a class="reference internal" href="#cascading-operations">Cascading Operations</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/embedded-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>
@@ -0,0 +1,796 @@
<!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>Events &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="events">
<h1>Events<a class="headerlink" href="#events" title="Permalink to this headline"></a></h1>
<p>Doctrine features a lightweight event system that is part of the
Common package.</p>
<div class="section" id="the-event-system">
<h2>The Event System<a class="headerlink" href="#the-event-system" title="Permalink to this headline"></a></h2>
<p>The event system is controlled by the <code class="docutils literal"><span class="pre">EventManager</span></code>. It is the
central point of Doctrine's event listener system. Listeners are
registered on the manager and events are dispatched through the
manager.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$evm</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventManager</span><span class="p">();</span>
</pre></div>
</div>
<p>Now we can add some event listeners to the <code class="docutils literal"><span class="pre">$evm</span></code>. Let's create a
<code class="docutils literal"><span class="pre">EventTest</span></code> class to play around with.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">class</span> <span class="nc">EventTest</span>
<span class="p">{</span>
<span class="k">const</span> <span class="no">preFoo</span> <span class="o">=</span> <span class="s1">&#39;preFoo&#39;</span><span class="p">;</span>
<span class="k">const</span> <span class="no">postFoo</span> <span class="o">=</span> <span class="s1">&#39;postFoo&#39;</span><span class="p">;</span>
<span class="k">private</span> <span class="nv">$_evm</span><span class="p">;</span>
<span class="k">public</span> <span class="nv">$preFooInvoked</span> <span class="o">=</span> <span class="k">false</span><span class="p">;</span>
<span class="k">public</span> <span class="nv">$postFooInvoked</span> <span class="o">=</span> <span class="k">false</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="nv">$evm</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$evm</span><span class="o">-&gt;</span><span class="na">addEventListener</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="nx">self</span><span class="o">::</span><span class="na">preFoo</span><span class="p">,</span> <span class="nx">self</span><span class="o">::</span><span class="na">postFoo</span><span class="p">),</span> <span class="nv">$this</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">preFoo</span><span class="p">(</span><span class="nx">EventArgs</span> <span class="nv">$e</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">preFooInvoked</span> <span class="o">=</span> <span class="k">true</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">postFoo</span><span class="p">(</span><span class="nx">EventArgs</span> <span class="nv">$e</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">postFooInvoked</span> <span class="o">=</span> <span class="k">true</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="c1">// Create a new instance</span>
<span class="nv">$test</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventTest</span><span class="p">(</span><span class="nv">$evm</span><span class="p">);</span>
</pre></div>
</div>
<p>Events can be dispatched by using the <code class="docutils literal"><span class="pre">dispatchEvent()</span></code> method.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$evm</span><span class="o">-&gt;</span><span class="na">dispatchEvent</span><span class="p">(</span><span class="nx">EventTest</span><span class="o">::</span><span class="na">preFoo</span><span class="p">);</span>
<span class="nv">$evm</span><span class="o">-&gt;</span><span class="na">dispatchEvent</span><span class="p">(</span><span class="nx">EventTest</span><span class="o">::</span><span class="na">postFoo</span><span class="p">);</span>
</pre></div>
</div>
<p>You can easily remove a listener with the <code class="docutils literal"><span class="pre">removeEventListener()</span></code>
method.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$evm</span><span class="o">-&gt;</span><span class="na">removeEventListener</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="nx">self</span><span class="o">::</span><span class="na">preFoo</span><span class="p">,</span> <span class="nx">self</span><span class="o">::</span><span class="na">postFoo</span><span class="p">),</span> <span class="nv">$this</span><span class="p">);</span>
</pre></div>
</div>
<p>The Doctrine event system also has a simple concept of event
subscribers. We can define a simple <code class="docutils literal"><span class="pre">TestEventSubscriber</span></code> class
which implements the <code class="docutils literal"><span class="pre">\Doctrine\Common\EventSubscriber</span></code> interface
and implements a <code class="docutils literal"><span class="pre">getSubscribedEvents()</span></code> method which returns an
array of events it should be subscribed to.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">class</span> <span class="nc">TestEventSubscriber</span> <span class="k">implements</span> <span class="nx">\Doctrine\Common\EventSubscriber</span>
<span class="p">{</span>
<span class="k">const</span> <span class="no">preFoo</span> <span class="o">=</span> <span class="s1">&#39;preFoo&#39;</span><span class="p">;</span>
<span class="k">public</span> <span class="nv">$preFooInvoked</span> <span class="o">=</span> <span class="k">false</span><span class="p">;</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">preFoo</span><span class="p">()</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">preFooInvoked</span> <span class="o">=</span> <span class="k">true</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">getSubscribedEvents</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">return</span> <span class="k">array</span><span class="p">(</span><span class="nx">self</span><span class="o">::</span><span class="na">preFoo</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="nv">$eventSubscriber</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">TestEventSubscriber</span><span class="p">();</span>
<span class="nv">$evm</span><span class="o">-&gt;</span><span class="na">addEventSubscriber</span><span class="p">(</span><span class="nv">$eventSubscriber</span><span class="p">);</span>
</pre></div>
</div>
<p>Now when you dispatch an event any event subscribers will be
notified for that event.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$evm</span><span class="o">-&gt;</span><span class="na">dispatchEvent</span><span class="p">(</span><span class="nx">TestEventSubscriber</span><span class="o">::</span><span class="na">preFoo</span><span class="p">);</span>
</pre></div>
</div>
<p>Now test the <code class="docutils literal"><span class="pre">$eventSubscriber</span></code> instance to see if the
<code class="docutils literal"><span class="pre">preFoo()</span></code> method was invoked.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$eventSubscriber</span><span class="o">-&gt;</span><span class="na">preFooInvoked</span><span class="p">)</span> <span class="p">{</span>
<span class="k">echo</span> <span class="s1">&#39;pre foo invoked!&#39;</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="lifecycle-events">
<span id="id1"></span><h2>Lifecycle Events<a class="headerlink" href="#lifecycle-events" title="Permalink to this headline"></a></h2>
<p>The DocumentManager and UnitOfWork trigger several events during
the life-time of their registered documents.</p>
<ul class="simple">
<li>preRemove - The preRemove event occurs for a given document before
the respective DocumentManager remove operation for that document
is executed.</li>
<li>postRemove - The postRemove event occurs for a document after the
document has been removed. It will be invoked after the database
delete operations.</li>
<li>prePersist - The prePersist event occurs for a given document
before the respective DocumentManager persist operation for that
document is executed.</li>
<li>postPersist - The postPersist event occurs for a document after
the document has been made persistent. It will be invoked after the
database insert operations. Generated primary key values are
available in the postPersist event.</li>
<li>preUpdate - The preUpdate event occurs before the database update
operations to document data.</li>
<li>postUpdate - The postUpdate event occurs after the database update
operations to document data.</li>
<li>preLoad - The preLoad event occurs for a document before the
document has been loaded into the current DocumentManager from the
database or after the refresh operation has been applied to it.</li>
<li>postLoad - The postLoad event occurs for a document after the
document has been loaded into the current DocumentManager from the
database or after the refresh operation has been applied to it.</li>
<li>loadClassMetadata - The loadClassMetadata event occurs after the
mapping metadata for a class has been loaded from a mapping source
(annotations/xml/yaml).</li>
<li>preFlush - The preFlush event occurs before the change-sets of all
managed documents are computed. This both a lifecycle call back and
and listener.</li>
<li>postFlush - The postFlush event occurs after the change-sets of all
managed documents are computed.</li>
<li>onFlush - The onFlush event occurs after the change-sets of all
managed documents are computed. This event is not a lifecycle
callback.</li>
<li>onClear - The onClear event occurs after the UnitOfWork has had
its state cleared.</li>
<li>documentNotFound - The documentNotFound event occurs when a proxy object
could not be initialized. This event is not a lifecycle callback.</li>
<li>postCollectionLoad - The postCollectionLoad event occurs just after
collection has been initialized (loaded) and before new elements
are re-added to it.</li>
</ul>
<p>You can access the Event constants from the <code class="docutils literal"><span class="pre">Events</span></code> class in the
ODM package.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\Events</span><span class="p">;</span>
<span class="k">echo</span> <span class="nx">Events</span><span class="o">::</span><span class="na">preUpdate</span><span class="p">;</span>
</pre></div>
</div>
<p>These can be hooked into by two different types of event
listeners:</p>
<ul class="simple">
<li>Lifecycle Callbacks are methods on the document classes that are
called when the event is triggered. They receive instances
of <code class="docutils literal"><span class="pre">Doctrine\ODM\MongoDB\Event\LifecycleEventArgs</span></code> (see relevant
examples below) as arguments and are specifically designed to allow
changes inside the document classes state.</li>
<li>Lifecycle Event Listeners are classes with specific callback
methods that receives some kind of <code class="docutils literal"><span class="pre">EventArgs</span></code> instance which
give access to the document, DocumentManager or other relevant
data.</li>
</ul>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">All Lifecycle events that happen during the <code class="docutils literal"><span class="pre">flush()</span></code> of
a DocumentManager have very specific constraints on the allowed
operations that can be executed. Please read the
<em>Implementing Event Listeners</em> section very carefully to understand
which operations are allowed in which lifecycle event.</p>
</div>
</div>
<div class="section" id="lifecycle-callbacks">
<h2>Lifecycle Callbacks<a class="headerlink" href="#lifecycle-callbacks" title="Permalink to this headline"></a></h2>
<p>A lifecycle event is a regular event with the additional feature of
providing a mechanism to register direct callbacks inside the
corresponding document classes that are executed when the lifecycle
event occurs.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/** @Document @HasLifecycleCallbacks */</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"> * @Field</span>
<span class="sd"> */</span>
<span class="k">public</span> <span class="nv">$value</span><span class="p">;</span>
<span class="sd">/** @Field */</span>
<span class="k">private</span> <span class="nv">$createdAt</span><span class="p">;</span>
<span class="sd">/** @PrePersist */</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">doStuffOnPrePersist</span><span class="p">(</span><span class="nx">\Doctrine\ODM\MongoDB\Event\LifecycleEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">createdAt</span> <span class="o">=</span> <span class="nb">date</span><span class="p">(</span><span class="s1">&#39;Y-m-d H:i:s&#39;</span><span class="p">);</span>
<span class="p">}</span>
<span class="sd">/** @PrePersist */</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">doOtherStuffOnPrePersist</span><span class="p">(</span><span class="nx">\Doctrine\ODM\MongoDB\Event\LifecycleEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">value</span> <span class="o">=</span> <span class="s1">&#39;changed from prePersist callback!&#39;</span><span class="p">;</span>
<span class="p">}</span>
<span class="sd">/** @PostPersist */</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">doStuffOnPostPersist</span><span class="p">(</span><span class="nx">\Doctrine\ODM\MongoDB\Event\LifecycleEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">value</span> <span class="o">=</span> <span class="s1">&#39;changed from postPersist callback!&#39;</span><span class="p">;</span>
<span class="p">}</span>
<span class="sd">/** @PreLoad */</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">doStuffOnPreLoad</span><span class="p">(</span><span class="nx">\Doctrine\ODM\MongoDB\Event\PreLoadEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$data</span> <span class="o">=&amp;</span> <span class="nv">$eventArgs</span><span class="o">-&gt;</span><span class="na">getData</span><span class="p">();</span>
<span class="nv">$data</span><span class="p">[</span><span class="s1">&#39;value&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;changed from preLoad callback&#39;</span><span class="p">;</span>
<span class="p">}</span>
<span class="sd">/** @PostLoad */</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">doStuffOnPostLoad</span><span class="p">(</span><span class="nx">\Doctrine\ODM\MongoDB\Event\LifecycleEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">value</span> <span class="o">=</span> <span class="s1">&#39;changed from postLoad callback!&#39;</span><span class="p">;</span>
<span class="p">}</span>
<span class="sd">/** @PreUpdate */</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">doStuffOnPreUpdate</span><span class="p">(</span><span class="nx">\Doctrine\ODM\MongoDB\Event\PreUpdateEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">value</span> <span class="o">=</span> <span class="s1">&#39;changed from preUpdate callback!&#39;</span><span class="p">;</span>
<span class="p">}</span>
<span class="sd">/** @PreFlush */</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">preFlush</span><span class="p">(</span><span class="nx">\Doctrine\ODM\MongoDB\Event\PreFlushEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">value</span> <span class="o">=</span> <span class="s1">&#39;changed from preFlush callback!&#39;</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Note that when using annotations you have to apply the
&#64;HasLifecycleCallbacks marker annotation on the document class.</p>
</div>
<div class="section" id="listening-to-lifecycle-events">
<h2>Listening to Lifecycle Events<a class="headerlink" href="#listening-to-lifecycle-events" title="Permalink to this headline"></a></h2>
<p>Lifecycle event listeners are much more powerful than the simple
lifecycle callbacks that are defined on the document classes. They
allow to implement re-usable behaviours between different document
classes, yet require much more detailed knowledge about the inner
workings of the DocumentManager and UnitOfWork. Please read the
<em>Implementing Event Listeners</em> section carefully if you are trying
to write your own listener.</p>
<p>To register an event listener you have to hook it into the
EventManager that is passed to the DocumentManager factory:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$eventManager</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventManager</span><span class="p">();</span>
<span class="nv">$eventManager</span><span class="o">-&gt;</span><span class="na">addEventListener</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="nx">Events</span><span class="o">::</span><span class="na">preUpdate</span><span class="p">),</span> <span class="k">new</span> <span class="nx">MyEventListener</span><span class="p">());</span>
<span class="nv">$eventManager</span><span class="o">-&gt;</span><span class="na">addEventSubscriber</span><span class="p">(</span><span class="k">new</span> <span class="nx">MyEventSubscriber</span><span class="p">());</span>
<span class="nv">$documentManager</span> <span class="o">=</span> <span class="nx">DocumentManager</span><span class="o">::</span><span class="na">create</span><span class="p">(</span><span class="nv">$mongo</span><span class="p">,</span> <span class="nv">$config</span><span class="p">,</span> <span class="nv">$eventManager</span><span class="p">);</span>
</pre></div>
</div>
<p>You can also retrieve the event manager instance after the
DocumentManager was created:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$documentManager</span><span class="o">-&gt;</span><span class="na">getEventManager</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">addEventListener</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="nx">Events</span><span class="o">::</span><span class="na">preUpdate</span><span class="p">),</span> <span class="k">new</span> <span class="nx">MyEventListener</span><span class="p">());</span>
<span class="nv">$documentManager</span><span class="o">-&gt;</span><span class="na">getEventManager</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">addEventSubscriber</span><span class="p">(</span><span class="k">new</span> <span class="nx">MyEventSubscriber</span><span class="p">());</span>
</pre></div>
</div>
</div>
<div class="section" id="implementing-event-listeners">
<h2>Implementing Event Listeners<a class="headerlink" href="#implementing-event-listeners" title="Permalink to this headline"></a></h2>
<p>This section explains what is and what is not allowed during
specific lifecycle events of the UnitOfWork. Although you get
passed the DocumentManager in all of these events, you have to
follow this restrictions very carefully since operations in the
wrong event may produce lots of different errors, such as
inconsistent data and lost updates/persists/removes.</p>
<div class="section" id="prepersist">
<h3>prePersist<a class="headerlink" href="#prepersist" title="Permalink to this headline"></a></h3>
<p>Listen to the <code class="docutils literal"><span class="pre">prePersist</span></code> event:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$test</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventTest</span><span class="p">();</span>
<span class="nv">$evm</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getEventManager</span><span class="p">();</span>
<span class="nv">$evm</span><span class="o">-&gt;</span><span class="na">addEventListener</span><span class="p">(</span><span class="nx">Events</span><span class="o">::</span><span class="na">prePersist</span><span class="p">,</span> <span class="nv">$test</span><span class="p">);</span>
</pre></div>
</div>
<p>Define the <code class="docutils literal"><span class="pre">EventTest</span></code> class:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">class</span> <span class="nc">EventTest</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">prePersist</span><span class="p">(</span><span class="nx">\Doctrine\ODM\MongoDB\Event\LifecycleEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$document</span> <span class="o">=</span> <span class="nv">$eventArgs</span><span class="o">-&gt;</span><span class="na">getDocument</span><span class="p">();</span>
<span class="nv">$document</span><span class="o">-&gt;</span><span class="na">setSomething</span><span class="p">();</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="preload">
<h3>preLoad<a class="headerlink" href="#preload" title="Permalink to this headline"></a></h3>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$test</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventTest</span><span class="p">();</span>
<span class="nv">$evm</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getEventManager</span><span class="p">();</span>
<span class="nv">$evm</span><span class="o">-&gt;</span><span class="na">addEventListener</span><span class="p">(</span><span class="nx">Events</span><span class="o">::</span><span class="na">preLoad</span><span class="p">,</span> <span class="nv">$test</span><span class="p">);</span>
</pre></div>
</div>
<p>Define the <code class="docutils literal"><span class="pre">EventTest</span></code> class with a <code class="docutils literal"><span class="pre">preLoad()</span></code> method:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">class</span> <span class="nc">EventTest</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">preLoad</span><span class="p">(</span><span class="nx">\Doctrine\ODM\MongoDB\Event\PreLoadEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$data</span> <span class="o">=&amp;</span> <span class="nv">$eventArgs</span><span class="o">-&gt;</span><span class="na">getData</span><span class="p">();</span>
<span class="c1">// do something</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="postload">
<h3>postLoad<a class="headerlink" href="#postload" title="Permalink to this headline"></a></h3>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$test</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventTest</span><span class="p">();</span>
<span class="nv">$evm</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getEventManager</span><span class="p">();</span>
<span class="nv">$evm</span><span class="o">-&gt;</span><span class="na">addEventListener</span><span class="p">(</span><span class="nx">Events</span><span class="o">::</span><span class="na">postLoad</span><span class="p">,</span> <span class="nv">$test</span><span class="p">);</span>
</pre></div>
</div>
<p>Define the <code class="docutils literal"><span class="pre">EventTest</span></code> class with a <code class="docutils literal"><span class="pre">postLoad()</span></code> method:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">class</span> <span class="nc">EventTest</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">postLoad</span><span class="p">(</span><span class="nx">\Doctrine\ODM\MongoDB\Event\LifecycleEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$document</span> <span class="o">=</span> <span class="nv">$eventArgs</span><span class="o">-&gt;</span><span class="na">getDocument</span><span class="p">();</span>
<span class="c1">// do something</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="preremove">
<h3>preRemove<a class="headerlink" href="#preremove" title="Permalink to this headline"></a></h3>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$test</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventTest</span><span class="p">();</span>
<span class="nv">$evm</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getEventManager</span><span class="p">();</span>
<span class="nv">$evm</span><span class="o">-&gt;</span><span class="na">addEventListener</span><span class="p">(</span><span class="nx">Events</span><span class="o">::</span><span class="na">preRemove</span><span class="p">,</span> <span class="nv">$test</span><span class="p">);</span>
</pre></div>
</div>
<p>Define the <code class="docutils literal"><span class="pre">EventTest</span></code> class with a <code class="docutils literal"><span class="pre">preRemove()</span></code> method:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">class</span> <span class="nc">EventTest</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">preRemove</span><span class="p">(</span><span class="nx">\Doctrine\ODM\MongoDB\Event\LifecycleEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$document</span> <span class="o">=</span> <span class="nv">$eventArgs</span><span class="o">-&gt;</span><span class="na">getDocument</span><span class="p">();</span>
<span class="c1">// do something</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="preflush">
<h3>preFlush<a class="headerlink" href="#preflush" title="Permalink to this headline"></a></h3>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$test</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventTest</span><span class="p">();</span>
<span class="nv">$evm</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getEventManager</span><span class="p">();</span>
<span class="nv">$evm</span><span class="o">-&gt;</span><span class="na">addEventListener</span><span class="p">(</span><span class="nx">Events</span><span class="o">::</span><span class="na">preFlush</span><span class="p">,</span> <span class="nv">$test</span><span class="p">);</span>
</pre></div>
</div>
<p>Define the <code class="docutils literal"><span class="pre">EventTest</span></code> class with a <code class="docutils literal"><span class="pre">preFlush()</span></code> method:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">class</span> <span class="nc">EventTest</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">preFlush</span><span class="p">(</span><span class="nx">\Doctrine\ODM\MongoDB\Event\PreFlushEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$dm</span> <span class="o">=</span> <span class="nv">$eventArgs</span><span class="o">-&gt;</span><span class="na">getDocumentManager</span><span class="p">();</span>
<span class="nv">$uow</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getUnitOfWork</span><span class="p">();</span>
<span class="c1">// do something</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="onflush">
<h3>onFlush<a class="headerlink" href="#onflush" title="Permalink to this headline"></a></h3>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$test</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventTest</span><span class="p">();</span>
<span class="nv">$evm</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getEventManager</span><span class="p">();</span>
<span class="nv">$evm</span><span class="o">-&gt;</span><span class="na">addEventListener</span><span class="p">(</span><span class="nx">Events</span><span class="o">::</span><span class="na">onFlush</span><span class="p">,</span> <span class="nv">$test</span><span class="p">);</span>
</pre></div>
</div>
<p>Define the <code class="docutils literal"><span class="pre">EventTest</span></code> class with a <code class="docutils literal"><span class="pre">onFlush()</span></code> method:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">class</span> <span class="nc">EventTest</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">onFlush</span><span class="p">(</span><span class="nx">\Doctrine\ODM\MongoDB\Event\OnFlushEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$dm</span> <span class="o">=</span> <span class="nv">$eventArgs</span><span class="o">-&gt;</span><span class="na">getDocumentManager</span><span class="p">();</span>
<span class="nv">$uow</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getUnitOfWork</span><span class="p">();</span>
<span class="c1">// do something</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="postflush">
<h3>postFlush<a class="headerlink" href="#postflush" title="Permalink to this headline"></a></h3>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$test</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventTest</span><span class="p">();</span>
<span class="nv">$evm</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getEventManager</span><span class="p">();</span>
<span class="nv">$evm</span><span class="o">-&gt;</span><span class="na">addEventListener</span><span class="p">(</span><span class="nx">Events</span><span class="o">::</span><span class="na">postFlush</span><span class="p">,</span> <span class="nv">$test</span><span class="p">);</span>
</pre></div>
</div>
<p>Define the <code class="docutils literal"><span class="pre">EventTest</span></code> class with a <code class="docutils literal"><span class="pre">postFlush()</span></code> method:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">class</span> <span class="nc">EventTest</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">postFlush</span><span class="p">(</span><span class="nx">\Doctrine\ODM\MongoDB\Event\PostFlushEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$dm</span> <span class="o">=</span> <span class="nv">$eventArgs</span><span class="o">-&gt;</span><span class="na">getDocumentManager</span><span class="p">();</span>
<span class="nv">$uow</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getUnitOfWork</span><span class="p">();</span>
<span class="c1">// do something</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="preupdate">
<h3>preUpdate<a class="headerlink" href="#preupdate" title="Permalink to this headline"></a></h3>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$test</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventTest</span><span class="p">();</span>
<span class="nv">$evm</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getEventManager</span><span class="p">();</span>
<span class="nv">$evm</span><span class="o">-&gt;</span><span class="na">addEventListener</span><span class="p">(</span><span class="nx">Events</span><span class="o">::</span><span class="na">preUpdate</span><span class="p">,</span> <span class="nv">$test</span><span class="p">);</span>
</pre></div>
</div>
<p>Define the <code class="docutils literal"><span class="pre">EventTest</span></code> class with a <code class="docutils literal"><span class="pre">preUpdate()</span></code> method:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">class</span> <span class="nc">EventTest</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">preUpdate</span><span class="p">(</span><span class="nx">\Doctrine\ODM\MongoDB\Event\LifecycleEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$document</span> <span class="o">=</span> <span class="nv">$eventArgs</span><span class="o">-&gt;</span><span class="na">getDocument</span><span class="p">();</span>
<span class="nv">$document</span><span class="o">-&gt;</span><span class="na">setSomething</span><span class="p">();</span>
<span class="nv">$dm</span> <span class="o">=</span> <span class="nv">$eventArgs</span><span class="o">-&gt;</span><span class="na">getDocumentManager</span><span class="p">();</span>
<span class="nv">$class</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getClassMetadata</span><span class="p">(</span><span class="nb">get_class</span><span class="p">(</span><span class="nv">$document</span><span class="p">));</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getUnitOfWork</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">recomputeSingleDocumentChangeSet</span><span class="p">(</span><span class="nv">$class</span><span class="p">,</span> <span class="nv">$document</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If you modify a document in the preUpdate event you must call <code class="docutils literal"><span class="pre">recomputeSingleDocumentChangeSet</span></code>
for the modified document in order for the changes to be persisted.</p>
</div>
</div>
<div class="section" id="onclear">
<h3>onClear<a class="headerlink" href="#onclear" title="Permalink to this headline"></a></h3>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$test</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventTest</span><span class="p">();</span>
<span class="nv">$evm</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getEventManager</span><span class="p">();</span>
<span class="nv">$evm</span><span class="o">-&gt;</span><span class="na">addEventListener</span><span class="p">(</span><span class="nx">Events</span><span class="o">::</span><span class="na">onClear</span><span class="p">,</span> <span class="nv">$test</span><span class="p">);</span>
</pre></div>
</div>
<p>Define the <code class="docutils literal"><span class="pre">EventTest</span></code> class with a <code class="docutils literal"><span class="pre">onClear()</span></code> method:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">class</span> <span class="nc">EventTest</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">onClear</span><span class="p">(</span><span class="nx">\Doctrine\ODM\MongoDB\Event\OnClearEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$class</span> <span class="o">=</span> <span class="nv">$eventArgs</span><span class="o">-&gt;</span><span class="na">getDocumentClass</span><span class="p">();</span>
<span class="nv">$dm</span> <span class="o">=</span> <span class="nv">$eventArgs</span><span class="o">-&gt;</span><span class="na">getDocumentManager</span><span class="p">();</span>
<span class="nv">$uow</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getUnitOfWork</span><span class="p">();</span>
<span class="c1">// Check if event clears all documents.</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$eventArgs</span><span class="o">-&gt;</span><span class="na">clearsAllDocuments</span><span class="p">())</span> <span class="p">{</span>
<span class="c1">// do something</span>
<span class="p">}</span>
<span class="c1">// do something</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="documentnotfound">
<h3>documentNotFound<a class="headerlink" href="#documentnotfound" title="Permalink to this headline"></a></h3>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$test</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventTest</span><span class="p">();</span>
<span class="nv">$evm</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getEventManager</span><span class="p">();</span>
<span class="nv">$evm</span><span class="o">-&gt;</span><span class="na">addEventListener</span><span class="p">(</span><span class="nx">Events</span><span class="o">::</span><span class="na">documentNotFound</span><span class="p">,</span> <span class="nv">$test</span><span class="p">);</span>
</pre></div>
</div>
<p>Define the <code class="docutils literal"><span class="pre">EventTest</span></code> class with a <code class="docutils literal"><span class="pre">documentNotFound()</span></code> method:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">class</span> <span class="nc">EventTest</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">documentNotFound</span><span class="p">(</span><span class="nx">\Doctrine\ODM\MongoDB\Event\DocumentNotFoundEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$proxy</span> <span class="o">=</span> <span class="nv">$eventArgs</span><span class="o">-&gt;</span><span class="na">getObject</span><span class="p">();</span>
<span class="nv">$identifier</span> <span class="o">=</span> <span class="nv">$eventArgs</span><span class="o">-&gt;</span><span class="na">getIdentifier</span><span class="p">();</span>
<span class="c1">// do something</span>
<span class="c1">// To prevent the documentNotFound exception from being thrown, call the disableException() method:</span>
<span class="nv">$eventArgs</span><span class="o">-&gt;</span><span class="na">disableException</span><span class="p">();</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="postupdate-postremove-postpersist">
<h3>postUpdate, postRemove, postPersist<a class="headerlink" href="#postupdate-postremove-postpersist" title="Permalink to this headline"></a></h3>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$test</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventTest</span><span class="p">();</span>
<span class="nv">$evm</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getEventManager</span><span class="p">();</span>
<span class="nv">$evm</span><span class="o">-&gt;</span><span class="na">addEventListener</span><span class="p">(</span><span class="nx">Events</span><span class="o">::</span><span class="na">postUpdate</span><span class="p">,</span> <span class="nv">$test</span><span class="p">);</span>
<span class="nv">$evm</span><span class="o">-&gt;</span><span class="na">addEventListener</span><span class="p">(</span><span class="nx">Events</span><span class="o">::</span><span class="na">postRemove</span><span class="p">,</span> <span class="nv">$test</span><span class="p">);</span>
<span class="nv">$evm</span><span class="o">-&gt;</span><span class="na">addEventListener</span><span class="p">(</span><span class="nx">Events</span><span class="o">::</span><span class="na">postPersist</span><span class="p">,</span> <span class="nv">$test</span><span class="p">);</span>
</pre></div>
</div>
<p>Define the <code class="docutils literal"><span class="pre">EventTest</span></code> class with a <code class="docutils literal"><span class="pre">postUpdate()</span></code>, <code class="docutils literal"><span class="pre">postRemove()</span></code> and <code class="docutils literal"><span class="pre">postPersist()</span></code> method:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">class</span> <span class="nc">EventTest</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">postUpdate</span><span class="p">(</span><span class="nx">\Doctrine\ODM\MongoDB\Event\LifecycleEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
<span class="p">{</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">postRemove</span><span class="p">(</span><span class="nx">\Doctrine\ODM\MongoDB\Event\LifecycleEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
<span class="p">{</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">postPersist</span><span class="p">(</span><span class="nx">\Doctrine\ODM\MongoDB\Event\LifecycleEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
<span class="p">{</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="postcollectionload">
<h3>postCollectionLoad<a class="headerlink" href="#postcollectionload" title="Permalink to this headline"></a></h3>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">This event was introduced in version 1.1</p>
</div>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$test</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventTest</span><span class="p">();</span>
<span class="nv">$evm</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getEventManager</span><span class="p">();</span>
<span class="nv">$evm</span><span class="o">-&gt;</span><span class="na">addEventListener</span><span class="p">(</span><span class="nx">Events</span><span class="o">::</span><span class="na">postCollectionLoad</span><span class="p">,</span> <span class="nv">$test</span><span class="p">);</span>
</pre></div>
</div>
<p>Define the <code class="docutils literal"><span class="pre">EventTest</span></code> class with a <code class="docutils literal"><span class="pre">postCollectionLoad()</span></code> method:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">class</span> <span class="nc">EventTest</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">postCollectionLoad</span><span class="p">(</span><span class="nx">\Doctrine\ODM\MongoDB\Event\PostCollectionLoadEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$collection</span> <span class="o">=</span> <span class="nv">$eventArgs</span><span class="o">-&gt;</span><span class="na">getCollection</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$collection</span> <span class="nx">instanceof</span> <span class="nx">\Malarzm\Collections\DiffableCollection</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$collection</span><span class="o">-&gt;</span><span class="na">snapshot</span><span class="p">();</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="load-classmetadata-event">
<h2>Load ClassMetadata Event<a class="headerlink" href="#load-classmetadata-event" title="Permalink to this headline"></a></h2>
<p>When the mapping information for a document is read, it is
populated in to a <code class="docutils literal"><span class="pre">ClassMetadata</span></code> instance. You can hook in to
this process and manipulate the instance with the <code class="docutils literal"><span class="pre">loadClassMetadata</span></code> event:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$test</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">EventTest</span><span class="p">();</span>
<span class="nv">$metadataFactory</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getMetadataFactory</span><span class="p">();</span>
<span class="nv">$evm</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getEventManager</span><span class="p">();</span>
<span class="nv">$evm</span><span class="o">-&gt;</span><span class="na">addEventListener</span><span class="p">(</span><span class="nx">Events</span><span class="o">::</span><span class="na">loadClassMetadata</span><span class="p">,</span> <span class="nv">$test</span><span class="p">);</span>
<span class="k">class</span> <span class="nc">EventTest</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">loadClassMetadata</span><span class="p">(</span><span class="nx">\Doctrine\ODM\MongoDB\Event\LoadClassMetadataEventArgs</span> <span class="nv">$eventArgs</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$classMetadata</span> <span class="o">=</span> <span class="nv">$eventArgs</span><span class="o">-&gt;</span><span class="na">getClassMetadata</span><span class="p">();</span>
<span class="nv">$fieldMapping</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span>
<span class="s1">&#39;fieldName&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;about&#39;</span><span class="p">,</span>
<span class="s1">&#39;type&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;string&#39;</span>
<span class="p">);</span>
<span class="nv">$classMetadata</span><span class="o">-&gt;</span><span class="na">mapField</span><span class="p">(</span><span class="nv">$fieldMapping</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</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="#">Events</a><ul>
<li><a class="reference internal" href="#the-event-system">The Event System</a></li>
<li><a class="reference internal" href="#lifecycle-events">Lifecycle Events</a></li>
<li><a class="reference internal" href="#lifecycle-callbacks">Lifecycle Callbacks</a></li>
<li><a class="reference internal" href="#listening-to-lifecycle-events">Listening to Lifecycle Events</a></li>
<li><a class="reference internal" href="#implementing-event-listeners">Implementing Event Listeners</a><ul>
<li><a class="reference internal" href="#prepersist">prePersist</a></li>
<li><a class="reference internal" href="#preload">preLoad</a></li>
<li><a class="reference internal" href="#postload">postLoad</a></li>
<li><a class="reference internal" href="#preremove">preRemove</a></li>
<li><a class="reference internal" href="#preflush">preFlush</a></li>
<li><a class="reference internal" href="#onflush">onFlush</a></li>
<li><a class="reference internal" href="#postflush">postFlush</a></li>
<li><a class="reference internal" href="#preupdate">preUpdate</a></li>
<li><a class="reference internal" href="#onclear">onClear</a></li>
<li><a class="reference internal" href="#documentnotfound">documentNotFound</a></li>
<li><a class="reference internal" href="#postupdate-postremove-postpersist">postUpdate, postRemove, postPersist</a></li>
<li><a class="reference internal" href="#postcollectionload">postCollectionLoad</a></li>
</ul>
</li>
<li><a class="reference internal" href="#load-classmetadata-event">Load ClassMetadata Event</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/events.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>
@@ -0,0 +1,228 @@
<!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>Filters &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="filters">
<span id="id1"></span><h1>Filters<a class="headerlink" href="#filters" title="Permalink to this headline"></a></h1>
<p>Doctrine features a filter system that allows the developer to add additional
criteria to queries, regardless of where the query is generated within the
application (e.g. from a query builder, loading referenced documents). This is
useful for excluding documents at a low level, to ensure that they are neither
returned from MongoDB nor hydrated by ODM.</p>
<div class="section" id="example-filter-class">
<h2>Example filter class<a class="headerlink" href="#example-filter-class" title="Permalink to this headline"></a></h2>
<p>Throughout this document, the example <code class="docutils literal"><span class="pre">MyLocaleFilter</span></code> class will be used to
illustrate how the filter feature works. A filter class must extend the base
<code class="docutils literal"><span class="pre">Doctrine\ODM\MongoDB\Query\Filter\BsonFilter</span></code> class and implement the
<code class="docutils literal"><span class="pre">addFilterCriteria()</span></code> method. This method receives <code class="docutils literal"><span class="pre">ClassMetadata</span></code> and is
invoked whenever a query is prepared for any class. Since filters are typically
designed with a specific class or interface in mind, <code class="docutils literal"><span class="pre">addFilterCriteria()</span></code>
will frequently start by checking <code class="docutils literal"><span class="pre">ClassMetadata</span></code> and returning immediately if
it is not supported.</p>
<p>Parameters for the query should be set on the filter object by calling the
<code class="docutils literal"><span class="pre">BsonFilter::setParameter()</span></code> method. Within the filter class, parameters
should be accessed via <code class="docutils literal"><span class="pre">BsonFilter::getParameter()</span></code>.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">namespace</span> <span class="nx">Vendor\Filter</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\Mapping\ClassMetadata</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\Query\Filter\BsonFilter</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">MyLocaleFilter</span> <span class="k">extends</span> <span class="nx">BsonFilter</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">addFilterCriteria</span><span class="p">(</span><span class="nx">ClassMetadata</span> <span class="nv">$targetDocument</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">// Check if the entity implements the LocalAware interface</span>
<span class="k">if</span> <span class="p">(</span> <span class="o">!</span> <span class="nv">$targetDocument</span><span class="o">-&gt;</span><span class="na">reflClass</span><span class="o">-&gt;</span><span class="na">implementsInterface</span><span class="p">(</span><span class="s1">&#39;LocaleAware&#39;</span><span class="p">))</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">array</span><span class="p">();</span>
<span class="p">}</span>
<span class="k">return</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;locale&#39;</span> <span class="o">=&gt;</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">getParameter</span><span class="p">(</span><span class="s1">&#39;locale&#39;</span><span class="p">));</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="configuration">
<h2>Configuration<a class="headerlink" href="#configuration" title="Permalink to this headline"></a></h2>
<p>Filter classes are added to the configuration as following:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$config</span><span class="o">-&gt;</span><span class="na">addFilter</span><span class="p">(</span><span class="s1">&#39;locale&#39;</span><span class="p">,</span> <span class="s1">&#39;\Vendor\Filter\MyLocaleFilter&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>The <code class="docutils literal"><span class="pre">Configuration#addFilter()</span></code> method takes a name for the filter and the
name of the filter class, which will be constructed as necessary.</p>
<p>An optional third parameter may be used to set parameters at configuration time:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$config</span><span class="o">-&gt;</span><span class="na">addFilter</span><span class="p">(</span><span class="s1">&#39;locale&#39;</span><span class="p">,</span> <span class="s1">&#39;\Vendor\Filter\MyLocaleFilter&#39;</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;locale&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;en&#39;</span><span class="p">));</span>
</pre></div>
</div>
</div>
<div class="section" id="disabling-enabling-filters-and-setting-parameters">
<h2>Disabling/Enabling Filters and Setting Parameters<a class="headerlink" href="#disabling-enabling-filters-and-setting-parameters" title="Permalink to this headline"></a></h2>
<p>Filters can be disabled and enabled via the <code class="docutils literal"><span class="pre">FilterCollection</span></code>, which is
stored in the <code class="docutils literal"><span class="pre">DocumentManager</span></code>. The <code class="docutils literal"><span class="pre">FilterCollection#enable($name)</span></code> method
may be used to enabled and return a filter, after which you may set parameters.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$filter</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getFilterCollection</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">enable</span><span class="p">(</span><span class="s2">&quot;locale&quot;</span><span class="p">);</span>
<span class="nv">$filter</span><span class="o">-&gt;</span><span class="na">setParameter</span><span class="p">(</span><span class="s1">&#39;locale&#39;</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;$in&#39;</span> <span class="o">=&gt;</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;en&#39;</span><span class="p">,</span> <span class="s1">&#39;fr&#39;</span><span class="p">));</span>
<span class="c1">// Disable the filter (perhaps temporarily to run an unfiltered query)</span>
<span class="nv">$filter</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getFilterCollection</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">disable</span><span class="p">(</span><span class="s2">&quot;locale&quot;</span><span class="p">);</span>
</pre></div>
</div>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<p class="last">Disabling and enabling filters has no effect on managed documents. If you
want to refresh or reload an object after having modified a filter or the
FilterCollection, then you should clear the DocumentManager and re-fetch
your documents so the new filtering rules may be applied.</p>
</div>
</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="#">Filters</a><ul>
<li><a class="reference internal" href="#example-filter-class">Example filter class</a></li>
<li><a class="reference internal" href="#configuration">Configuration</a></li>
<li><a class="reference internal" href="#disabling-enabling-filters-and-setting-parameters">Disabling/Enabling Filters and Setting Parameters</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/filters.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>
@@ -0,0 +1,219 @@
<!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>Find and Modify &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="find-and-modify">
<h1>Find and Modify<a class="headerlink" href="#find-and-modify" title="Permalink to this headline"></a></h1>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p>From MongoDB.org:</p>
<p class="last">MongoDB supports a &quot;find, modify, and return&quot; command. This command
can be used to atomically modify a document (at most one) and
return it. Note that, by default, the document returned will not
include the modifications made on the update.</p>
</div>
<p>Doctrine fully integrates the find and modify functionality to the
query builder object so you can easily run these types of queries!</p>
<div class="section" id="update">
<h2>Update<a class="headerlink" href="#update" title="Permalink to this headline"></a></h2>
<p>For example you can update a job and return it:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$job</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;Job&#39;</span><span class="p">)</span>
<span class="c1">// Find the job</span>
<span class="o">-&gt;</span><span class="na">findAndUpdate</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;in_progress&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">equals</span><span class="p">(</span><span class="k">false</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">sort</span><span class="p">(</span><span class="s1">&#39;priority&#39;</span><span class="p">,</span> <span class="s1">&#39;desc&#39;</span><span class="p">)</span>
<span class="c1">// Update found job</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;started&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span><span class="k">new</span> <span class="nx">\MongoDate</span><span class="p">())</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;in_progress&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span><span class="k">true</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
</pre></div>
</div>
<p>If you want to update a job and return the new document you can
call the <code class="docutils literal"><span class="pre">returnNew()</span></code> method.</p>
<p>Here is an example where we return the new updated job document:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$job</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;Job&#39;</span><span class="p">)</span>
<span class="c1">// Find the job</span>
<span class="o">-&gt;</span><span class="na">findAndUpdate</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">returnNew</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;in_progress&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">equals</span><span class="p">(</span><span class="k">false</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">sort</span><span class="p">(</span><span class="s1">&#39;priority&#39;</span><span class="p">,</span> <span class="s1">&#39;desc&#39;</span><span class="p">)</span>
<span class="c1">// Update found job</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;started&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span><span class="k">new</span> <span class="nx">\MongoDate</span><span class="p">())</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;in_progress&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">set</span><span class="p">(</span><span class="k">true</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
</pre></div>
</div>
<p>The returned <code class="docutils literal"><span class="pre">$job</span></code> will be a managed <code class="docutils literal"><span class="pre">Job</span></code> instance with the
<code class="docutils literal"><span class="pre">started</span></code> and <code class="docutils literal"><span class="pre">in_progress</span></code> fields updated.</p>
</div>
<div class="section" id="remove">
<h2>Remove<a class="headerlink" href="#remove" title="Permalink to this headline"></a></h2>
<p>You can also remove a document and return it:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$job</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;Job&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">findAndRemove</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">sort</span><span class="p">(</span><span class="s1">&#39;priority&#39;</span><span class="p">,</span> <span class="s1">&#39;desc&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
</pre></div>
</div>
<p>You can read more about the find and modify functionality on the
<a class="reference external" href="https://docs.mongodb.com/manual/reference/method/db.collection.findAndModify/">MongoDB website</a>.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If you don't need to return the document, you can use just run a normal update which can
affect multiple documents, as well. For multiple update to happen you need to use
<code class="docutils literal"><span class="pre">-&gt;updateMany()</span></code> method of the builder (or <code class="docutils literal"><span class="pre">update()-&gt;multiple()</span></code> combination that
was deprecated in version 1.2).</p>
</div>
</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="#">Find and Modify</a><ul>
<li><a class="reference internal" href="#update">Update</a></li>
<li><a class="reference internal" href="#remove">Remove</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/find-and-update.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>
@@ -0,0 +1,276 @@
<!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>Geospatial Queries &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="geospatial-queries">
<h1>Geospatial Queries<a class="headerlink" href="#geospatial-queries" title="Permalink to this headline"></a></h1>
<p>You can execute some special queries when using geospatial indexes
like checking for documents within a rectangle or circle.</p>
<div class="section" id="mapping">
<h2>Mapping<a class="headerlink" href="#mapping" title="Permalink to this headline"></a></h2>
<p>First, setup some documents like the following:</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"> * @Document</span>
<span class="sd"> * @Index(keys={&quot;coordinates&quot;=&quot;2d&quot;})</span>
<span class="sd"> */</span>
<span class="k">class</span> <span class="nc">City</span>
<span class="p">{</span>
<span class="sd">/** @Id */</span>
<span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">public</span> <span class="nv">$name</span><span class="p">;</span>
<span class="sd">/** @EmbedOne(targetDocument=&quot;Coordinates&quot;) */</span>
<span class="k">public</span> <span class="nv">$coordinates</span><span class="p">;</span>
<span class="sd">/** @Distance */</span>
<span class="k">public</span> <span class="nv">$distance</span><span class="p">;</span>
<span class="p">}</span>
<span class="sd">/** @EmbeddedDocument */</span>
<span class="k">class</span> <span class="nc">Coordinates</span>
<span class="p">{</span>
<span class="sd">/** @Field(type=&quot;float&quot;) */</span>
<span class="k">public</span> <span class="nv">$x</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;float&quot;) */</span>
<span class="k">public</span> <span class="nv">$y</span><span class="p">;</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;indexes&gt;</span>
<span class="nt">&lt;index&gt;</span>
<span class="nt">&lt;key</span> <span class="na">name=</span><span class="s">&quot;coordinates&quot;</span> <span class="na">order=</span><span class="s">&quot;2d&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/index&gt;</span>
<span class="nt">&lt;/indexes&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">indexes</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">coordinates</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">keys</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">coordinates</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">2d</span>
</pre></div>
</div>
</li>
</ul>
</div>
</div>
<div class="section" id="near-query">
<h2>Near Query<a class="headerlink" href="#near-query" title="Permalink to this headline"></a></h2>
<p>Now you can execute queries against these documents like the
following. Check for the 10 nearest cities to a given longitude
and latitude with the <code class="docutils literal"><span class="pre">near($longitude,</span> <span class="pre">$latitude)</span></code> method:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$cities</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">dm</span><span class="o">-&gt;</span><span class="na">createQuery</span><span class="p">(</span><span class="s1">&#39;City&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;coordinates&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">near</span><span class="p">(</span><span class="o">-</span><span class="mi">120</span><span class="p">,</span> <span class="mi">40</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
</pre></div>
</div>
</div>
<div class="section" id="geonear-command">
<span id="geonear"></span><h2>GeoNear Command<a class="headerlink" href="#geonear-command" title="Permalink to this headline"></a></h2>
<p>You can also execute the <a class="reference external" href="https://docs.mongodb.com/manual/reference/command/geoNear/">geoNear command</a> using the query builder's
<code class="docutils literal"><span class="pre">geoNear()</span></code> method. Additional builder methods can be used to set options for
this command (e.g. <code class="docutils literal"><span class="pre">distanceMultipler()</span></code>, <code class="docutils literal"><span class="pre">maxDistance()</span></code>, <code class="docutils literal"><span class="pre">spherical()</span></code>).
Unlike <code class="docutils literal"><span class="pre">near()</span></code>, which uses a query operator, <code class="docutils literal"><span class="pre">geoNear()</span></code> does not require
the location field to be specified in the builder, as MongoDB will use the
single geospatial index for the collection. Documents will be returned in order
of nearest to farthest.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$cities</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">dm</span><span class="o">-&gt;</span><span class="na">createQuery</span><span class="p">(</span><span class="s1">&#39;City&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">geoNear</span><span class="p">(</span><span class="o">-</span><span class="mi">120</span><span class="p">,</span> <span class="mi">40</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">spherical</span><span class="p">(</span><span class="k">true</span><span class="p">)</span>
<span class="c1">// Convert radians to kilometers (use 3963.192 for miles)</span>
<span class="o">-&gt;</span><span class="na">distanceMultiplier</span><span class="p">(</span><span class="mf">6378.137</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
</pre></div>
</div>
<p>If the model has a property mapped with <a class="reference internal" href="annotations-reference.html#annotation-distance"><span class="std std-ref">&#64;Distance</span></a>,
that field will be set with the calculated distance between the document and the
query coordinates.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$cities</span> <span class="k">as</span> <span class="nv">$city</span><span class="p">)</span> <span class="p">{</span>
<span class="nb">printf</span><span class="p">(</span><span class="s2">&quot;%s is %f kilometers away.</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="nv">$city</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">,</span> <span class="nv">$city</span><span class="o">-&gt;</span><span class="na">distance</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
<div class="section" id="within-box">
<h2>Within Box<a class="headerlink" href="#within-box" title="Permalink to this headline"></a></h2>
<p>You can also query for cities within a given rectangle using the
<code class="docutils literal"><span class="pre">withinBox($x1,</span> <span class="pre">$y1,</span> <span class="pre">$x2,</span> <span class="pre">$y2)</span></code> method:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$cities</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">dm</span><span class="o">-&gt;</span><span class="na">createQuery</span><span class="p">(</span><span class="s1">&#39;City&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;coordinates&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">withinBox</span><span class="p">(</span><span class="mi">41</span><span class="p">,</span> <span class="mi">41</span><span class="p">,</span> <span class="mi">72</span><span class="p">,</span> <span class="mi">72</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
</pre></div>
</div>
</div>
<div class="section" id="within-center">
<h2>Within Center<a class="headerlink" href="#within-center" title="Permalink to this headline"></a></h2>
<p>In addition to boxes you can check for cities within a circle using
the <code class="docutils literal"><span class="pre">withinCenter($x,</span> <span class="pre">$y,</span> <span class="pre">$radius)</span></code> method:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$cities</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">dm</span><span class="o">-&gt;</span><span class="na">createQuery</span><span class="p">(</span><span class="s1">&#39;City&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;coordinates&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">withinCenter</span><span class="p">(</span><span class="mi">50</span><span class="p">,</span> <span class="mi">50</span><span class="p">,</span> <span class="mi">20</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
</pre></div>
</div>
</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="#">Geospatial Queries</a><ul>
<li><a class="reference internal" href="#mapping">Mapping</a></li>
<li><a class="reference internal" href="#near-query">Near Query</a></li>
<li><a class="reference internal" href="#geonear-command">GeoNear Command</a></li>
<li><a class="reference internal" href="#within-box">Within Box</a></li>
<li><a class="reference internal" href="#within-center">Within Center</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/geospatial-queries.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>
@@ -0,0 +1,677 @@
<!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>Indexes &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="indexes">
<h1>Indexes<a class="headerlink" href="#indexes" title="Permalink to this headline"></a></h1>
<p>Working with indexes in the MongoDB ODM is pretty straight forward.
You can have multiple indexes, they can consist of multiple fields,
they can be unique and you can give them an order. In this chapter
we'll show you examples of indexes using annotations.</p>
<p>First here is an example where we put an index on a single
property:</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="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
<span class="sd">/** @Document */</span>
<span class="k">class</span> <span class="nc">User</span>
<span class="p">{</span>
<span class="sd">/** @Id */</span>
<span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) @Index */</span>
<span class="k">public</span> <span class="nv">$username</span><span class="p">;</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">name=</span><span class="s">&quot;username&quot;</span> <span class="na">index=</span><span class="s">&quot;true&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">fields</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">username</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">index</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
</pre></div>
</div>
</li>
</ul>
</div>
<div class="section" id="index-options">
<h2>Index Options<a class="headerlink" href="#index-options" title="Permalink to this headline"></a></h2>
<p>You can customize the index with some additional options:</p>
<ul class="simple">
<li><strong>name</strong> - The name of the index. This can be useful if you are
indexing many keys and Mongo complains about the index name being
too long.</li>
<li><strong>dropDups</strong> - If a unique index is being created and duplicate
values exist, drop all but one duplicate value.</li>
<li><strong>background</strong> - Create indexes in the background while other
operations are taking place. By default, index creation happens
synchronously. If you specify TRUE with this option, index creation
will be asynchronous.</li>
<li><strong>safe</strong> - You can specify a boolean value for checking if the
index creation succeeded. The driver will throw a
MongoCursorException if index creation failed.</li>
<li><strong>expireAfterSeconds</strong> - If you specify this option then the associated
document will be automatically removed when the provided time (in seconds)
has passed. This option is bound to a number of limitations, which
are documented at <a class="reference external" href="https://docs.mongodb.com/manual/tutorial/expire-data/">https://docs.mongodb.com/manual/tutorial/expire-data/</a>.</li>
<li><strong>order</strong> - The order of the index (asc or desc).</li>
<li><strong>unique</strong> - Create a unique index.</li>
<li><strong>sparse</strong> - Create a sparse index. If a unique index is being created
the sparse option will allow duplicate null entries, but the field must be
unique otherwise.</li>
<li><strong>partialFilterExpression</strong> - Create a partial index. Partial indexes only
index the documents in a collection that meet a specified filter expression.
By indexing a subset of the documents in a collection, partial indexes have
lower storage requirements and reduced performance costs for index creation
and maintenance. This feature was introduced with MongoDB 3.2 and is not
available on older versions.</li>
</ul>
</div>
<div class="section" id="unique-index">
<h2>Unique Index<a class="headerlink" href="#unique-index" title="Permalink to this headline"></a></h2>
<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="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
<span class="sd">/** @Document */</span>
<span class="k">class</span> <span class="nc">User</span>
<span class="p">{</span>
<span class="sd">/** @Id */</span>
<span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) @Index(unique=true, order=&quot;asc&quot;) */</span>
<span class="k">public</span> <span class="nv">$username</span><span class="p">;</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;username&quot;</span> <span class="na">index=</span><span class="s">&quot;true&quot;</span> <span class="na">unique=</span><span class="s">&quot;true&quot;</span> <span class="na">order=</span><span class="s">&quot;asc&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">fields</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">username</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">index</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
<span class="l l-Scalar l-Scalar-Plain">unique</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
<span class="l l-Scalar l-Scalar-Plain">order</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
</pre></div>
</div>
</li>
</ul>
</div>
<p>For your convenience you can quickly specify a unique index with
<code class="docutils literal"><span class="pre">&#64;UniqueIndex</span></code>:</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="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
<span class="sd">/** @Document */</span>
<span class="k">class</span> <span class="nc">User</span>
<span class="p">{</span>
<span class="sd">/** @Id */</span>
<span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) @UniqueIndex(order=&quot;asc&quot;) */</span>
<span class="k">public</span> <span class="nv">$username</span><span class="p">;</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;username&quot;</span> <span class="na">unique=</span><span class="s">&quot;true&quot;</span> <span class="na">order=</span><span class="s">&quot;asc&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">fields</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">username</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">unique</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
<span class="l l-Scalar l-Scalar-Plain">order</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
</pre></div>
</div>
</li>
</ul>
</div>
<p>If you want to specify an index that consists of multiple fields
you can specify them on the class doc block:</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="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
<span class="sd">/**</span>
<span class="sd"> * @Document</span>
<span class="sd"> * @UniqueIndex(keys={&quot;accountId&quot;=&quot;asc&quot;, &quot;username&quot;=&quot;asc&quot;})</span>
<span class="sd"> */</span>
<span class="k">class</span> <span class="nc">User</span>
<span class="p">{</span>
<span class="sd">/** @Id */</span>
<span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;int&quot;) */</span>
<span class="k">public</span> <span class="nv">$accountId</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">public</span> <span class="nv">$username</span><span class="p">;</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;doctrine-mongo-mapping</span> <span class="na">xmlns=</span><span class="s">&quot;http://doctrine-project.org/schemas/orm/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/orm/doctrine-mongo-mapping</span>
<span class="s"> http://doctrine-project.org/schemas/orm/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\User&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;indexes&gt;</span>
<span class="nt">&lt;index&gt;</span>
<span class="nt">&lt;option</span> <span class="na">name=</span><span class="s">&quot;unique&quot;</span> <span class="na">value=</span><span class="s">&quot;true&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;key</span> <span class="na">name=</span><span class="s">&quot;accountId&quot;</span> <span class="na">order=</span><span class="s">&quot;asc&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;key</span> <span class="na">name=</span><span class="s">&quot;username&quot;</span> <span class="na">order=</span><span class="s">&quot;asc&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/index&gt;</span>
<span class="nt">&lt;/indexes&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">Documents\User</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">indexes</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">usernameacctid</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">options</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">unique</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
<span class="l l-Scalar l-Scalar-Plain">keys</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">accountId</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">order</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">asc</span>
<span class="l l-Scalar l-Scalar-Plain">username</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">order</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">asc</span>
</pre></div>
</div>
</li>
</ul>
</div>
<p>To specify multiple indexes you must use the <code class="docutils literal"><span class="pre">&#64;Indexes</span></code>
annotation:</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"> * @Document</span>
<span class="sd"> * @Indexes({</span>
<span class="sd"> * @Index(keys={&quot;accountId&quot;=&quot;asc&quot;}),</span>
<span class="sd"> * @Index(keys={&quot;username&quot;=&quot;asc&quot;})</span>
<span class="sd"> * })</span>
<span class="sd"> */</span>
<span class="k">class</span> <span class="nc">User</span>
<span class="p">{</span>
<span class="sd">/** @Id */</span>
<span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;int&quot;) */</span>
<span class="k">public</span> <span class="nv">$accountId</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">public</span> <span class="nv">$username</span><span class="p">;</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;doctrine-mongo-mapping</span> <span class="na">xmlns=</span><span class="s">&quot;http://doctrine-project.org/schemas/orm/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/orm/doctrine-mongo-mapping</span>
<span class="s"> http://doctrine-project.org/schemas/orm/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\User&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;indexes&gt;</span>
<span class="nt">&lt;index&gt;</span>
<span class="nt">&lt;key</span> <span class="na">name=</span><span class="s">&quot;accountId&quot;</span> <span class="na">order=</span><span class="s">&quot;asc&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/index&gt;</span>
<span class="nt">&lt;index&gt;</span>
<span class="nt">&lt;key</span> <span class="na">name=</span><span class="s">&quot;username&quot;</span> <span class="na">order=</span><span class="s">&quot;asc&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/index&gt;</span>
<span class="nt">&lt;/indexes&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">Documents\User</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">indexes</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">accountId</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">keys</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">accountId</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">order</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">asc</span>
<span class="l l-Scalar l-Scalar-Plain">username</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">keys</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">username</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">order</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">asc</span>
</pre></div>
</div>
</li>
</ul>
</div>
</div>
<div class="section" id="embedded-indexes">
<h2>Embedded Indexes<a class="headerlink" href="#embedded-indexes" title="Permalink to this headline"></a></h2>
<p>You can specify indexes on embedded documents just like you do on normal documents. When Doctrine
creates the indexes for a document it will also create all the indexes from its mapped embedded
documents.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
<span class="sd">/** @EmbeddedDocument */</span>
<span class="k">class</span> <span class="nc">Comment</span>
<span class="p">{</span>
<span class="sd">/** @Field(type=&quot;date&quot;) @Index */</span>
<span class="k">private</span> <span class="nv">$date</span><span class="p">;</span>
<span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Now if we had a <code class="docutils literal"><span class="pre">BlogPost</span></code> document with the <code class="docutils literal"><span class="pre">Comment</span></code> document embedded many times:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
<span class="sd">/** @Document */</span>
<span class="k">class</span> <span class="nc">BlogPost</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="sd">/** @Field(type=&quot;string&quot;) @Index */</span>
<span class="k">private</span> <span class="nv">$slug</span><span class="p">;</span>
<span class="sd">/** @EmbedMany(targetDocument=&quot;Comment&quot;) */</span>
<span class="k">private</span> <span class="nv">$comments</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>If we were to create the indexes with the <code class="docutils literal"><span class="pre">SchemaManager</span></code>:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$sm</span><span class="o">-&gt;</span><span class="na">ensureIndexes</span><span class="p">();</span>
</pre></div>
</div>
<p>It will create the indexes from the <code class="docutils literal"><span class="pre">BlogPost</span></code> document but will also create the indexes that are
defined on the <code class="docutils literal"><span class="pre">Comment</span></code> embedded document. The following would be executed on the underlying MongoDB
database:</p>
<blockquote>
<div>db.BlogPost.ensureIndexes({ 'slug' : 1, 'comments.date': 1 })</div></blockquote>
<p>Also, for your convenience you can create the indexes for your mapped documents from the
<a class="reference internal" href="console-commands.html"><span class="doc">console</span></a>:</p>
<blockquote>
<div>$ php mongodb.php mongodb:schema:create --index</div></blockquote>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If you are <a class="reference internal" href="embedded-mapping.html#embed-mixing-document-types"><span class="std std-ref">mixing document types</span></a> for your
embedded documents, ODM will not be able to create indexes for their fields
unless you specify a discriminator map for the <a class="reference internal" href="embedded-mapping.html#embed-one"><span class="std std-ref">embed-one</span></a>
or <a class="reference internal" href="embedded-mapping.html#embed-many"><span class="std std-ref">embed-many</span></a> relationship.</p>
</div>
</div>
<div class="section" id="geospatial-indexing">
<h2>Geospatial Indexing<a class="headerlink" href="#geospatial-indexing" title="Permalink to this headline"></a></h2>
<p>You can specify a geospatial index by just specifying the keys and
options structures manually:</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"> * @Document</span>
<span class="sd"> * @Index(keys={&quot;coordinates&quot;=&quot;2d&quot;})</span>
<span class="sd"> */</span>
<span class="k">class</span> <span class="nc">Place</span>
<span class="p">{</span>
<span class="sd">/** @Id */</span>
<span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>
<span class="sd">/** @EmbedOne(targetDocument=&quot;Coordinates&quot;) */</span>
<span class="k">public</span> <span class="nv">$coordinates</span><span class="p">;</span>
<span class="p">}</span>
<span class="sd">/** @EmbeddedDocument */</span>
<span class="k">class</span> <span class="nc">Coordinates</span>
<span class="p">{</span>
<span class="sd">/** @Field(type=&quot;float&quot;) */</span>
<span class="k">public</span> <span class="nv">$latitude</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;float&quot;) */</span>
<span class="k">public</span> <span class="nv">$longitude</span><span class="p">;</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;indexes&gt;</span>
<span class="nt">&lt;index&gt;</span>
<span class="nt">&lt;key</span> <span class="na">name=</span><span class="s">&quot;coordinates&quot;</span> <span class="na">order=</span><span class="s">&quot;2d&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/index&gt;</span>
<span class="nt">&lt;/indexes&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">indexes</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">coordinates</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">keys</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">coordinates</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">2d</span>
</pre></div>
</div>
</li>
</ul>
</div>
</div>
<div class="section" id="partial-indexes">
<h2>Partial indexes<a class="headerlink" href="#partial-indexes" title="Permalink to this headline"></a></h2>
<p>You can create a partial index by adding a <code class="docutils literal"><span class="pre">partialFilterExpression</span></code> to any
index.</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"> * @Document</span>
<span class="sd"> * @Index(keys={&quot;city&quot;=&quot;asc&quot;}, partialFilterExpression={&quot;version&quot;={&quot;$gt&quot;=1}})</span>
<span class="sd"> */</span>
<span class="k">class</span> <span class="nc">Place</span>
<span class="p">{</span>
<span class="sd">/** @Id */</span>
<span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">public</span> <span class="nv">$city</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;int&quot;) */</span>
<span class="k">public</span> <span class="nv">$version</span><span class="p">;</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;indexes&gt;</span>
<span class="nt">&lt;index&gt;</span>
<span class="nt">&lt;key</span> <span class="na">name=</span><span class="s">&quot;city&quot;</span> <span class="na">order=</span><span class="s">&quot;asc&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;partial-filter-expression&gt;</span>
<span class="nt">&lt;field</span> <span class="na">name=</span><span class="s">&quot;version&quot;</span> <span class="na">value=</span><span class="s">&quot;1&quot;</span> <span class="na">operator=</span><span class="s">&quot;gt&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/partial-filter-expression&gt;</span>
<span class="nt">&lt;/index&gt;</span>
<span class="nt">&lt;/indexes&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">indexes</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">partialIndexExample</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">keys</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">coordinates</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">asc</span>
<span class="l l-Scalar l-Scalar-Plain">options</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">partialFilterExpression</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">version</span><span class="p p-Indicator">:</span> <span class="p p-Indicator">{</span> <span class="nv">$gt</span><span class="p p-Indicator">:</span> <span class="nv">1</span> <span class="p p-Indicator">}</span>
</pre></div>
</div>
</li>
</ul>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Partial indexes are only available with MongoDB 3.2 or newer. For more
information on partial filter expressions, read the
<a class="reference external" href="https://docs.mongodb.com/manual/core/index-partial/">official MongoDB documentation</a>.</p>
</div>
</div>
<div class="section" id="requiring-indexes">
<h2>Requiring Indexes<a class="headerlink" href="#requiring-indexes" title="Permalink to this headline"></a></h2>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Requiring Indexes was deprecated in 1.2 and will be removed in 2.0.</p>
</div>
<p>Sometimes you may want to require indexes for all your queries to ensure you don't let stray unindexed queries
make it to the database and cause performance problems.</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"> * @Document(requireIndexes=true)</span>
<span class="sd"> */</span>
<span class="k">class</span> <span class="nc">Place</span>
<span class="p">{</span>
<span class="sd">/** @Id */</span>
<span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) @Index */</span>
<span class="k">public</span> <span class="nv">$city</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
</li>
<li><em>XML</em><div class="highlight-xml"><div class="highlight"><pre>// Documents.Place.dcm.xml
<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/orm/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/orm/doctrine-mongo-mapping</span>
<span class="s"> http://doctrine-project.org/schemas/orm/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\Place&quot;</span> <span class="na">require-indexes=</span><span class="s">&quot;true&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;field</span> <span class="na">fieldName=</span><span class="s">&quot;id&quot;</span> <span class="na">id=</span><span class="s">&quot;true&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;field</span> <span class="na">fieldName=</span><span class="s">&quot;city&quot;</span> <span class="na">type=</span><span class="s">&quot;string&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;indexes&gt;</span>
<span class="nt">&lt;index&gt;</span>
<span class="nt">&lt;key</span> <span class="na">name=</span><span class="s">&quot;city&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;/index&gt;</span>
<span class="nt">&lt;/indexes&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="c1"># Documents.Place.dcm.yml</span>
<span class="l l-Scalar l-Scalar-Plain">Documents\Place</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">fields</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">id</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">id</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
<span class="l l-Scalar l-Scalar-Plain">city</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">string</span>
<span class="l l-Scalar l-Scalar-Plain">indexes</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">index1</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">keys</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">city</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">asc</span>
</pre></div>
</div>
</li>
</ul>
</div>
<p>When you run queries it will check that it is indexed and throw an exception if it is not indexed:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$qb</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;Documents\Place&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;city&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">equals</span><span class="p">(</span><span class="s1">&#39;Nashville&#39;</span><span class="p">);</span>
<span class="nv">$query</span> <span class="o">=</span> <span class="nv">$qb</span><span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">();</span>
<span class="nv">$places</span> <span class="o">=</span> <span class="nv">$query</span><span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
</pre></div>
</div>
<p>When you execute the query it will throw an exception if <cite>city</cite> was not indexed in the database. You can control
whether or not an exception will be thrown by using the <cite>requireIndexes()</cite> method:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$qb</span><span class="o">-&gt;</span><span class="na">requireIndexes</span><span class="p">(</span><span class="k">false</span><span class="p">);</span>
</pre></div>
</div>
<p>You can also check if the query is indexed and with the <cite>isIndexed()</cite> method and use it to display your
own notification when a query is unindexed:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$query</span> <span class="o">=</span> <span class="nv">$qb</span><span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nv">$query</span><span class="o">-&gt;</span><span class="na">isIndexed</span><span class="p">())</span> <span class="p">{</span>
<span class="nv">$notifier</span><span class="o">-&gt;</span><span class="na">addError</span><span class="p">(</span><span class="s1">&#39;Cannot execute queries that are not indexed.&#39;</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<p>If you don't want to require indexes for all queries you can set leave <cite>requireIndexes</cite> as false and control
it on a per query basis:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$qb</span><span class="o">-&gt;</span><span class="na">requireIndexes</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>
<span class="nv">$query</span> <span class="o">=</span> <span class="nv">$qb</span><span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">();</span>
<span class="nv">$results</span> <span class="o">=</span> <span class="nv">$query</span><span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
</pre></div>
</div>
</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="#">Indexes</a><ul>
<li><a class="reference internal" href="#index-options">Index Options</a></li>
<li><a class="reference internal" href="#unique-index">Unique Index</a></li>
<li><a class="reference internal" href="#embedded-indexes">Embedded Indexes</a></li>
<li><a class="reference internal" href="#geospatial-indexing">Geospatial Indexing</a></li>
<li><a class="reference internal" href="#partial-indexes">Partial indexes</a></li>
<li><a class="reference internal" href="#requiring-indexes">Requiring Indexes</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/indexes.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>
@@ -0,0 +1,416 @@
<!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>Inheritance 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="inheritance-mapping">
<span id="id1"></span><h1>Inheritance Mapping<a class="headerlink" href="#inheritance-mapping" title="Permalink to this headline"></a></h1>
<p>Doctrine currently offers two supported methods of inheritance:
<a class="reference internal" href="#single-collection-inheritance"><span class="std std-ref">single collection</span></a> and
<a class="reference internal" href="#collection-per-class-inheritance"><span class="std std-ref">collection per class</span></a> inheritance.</p>
<div class="section" id="mapped-superclasses">
<h2>Mapped Superclasses<a class="headerlink" href="#mapped-superclasses" title="Permalink to this headline"></a></h2>
<p>A mapped superclass is an abstract or concrete class that provides mapping
information for its subclasses, but is not itself a document. Typically, the
purpose of such a mapped superclass is to define state and mapping information
that is common to multiple document classes.</p>
<p>Just like non-mapped classes, mapped superclasses may appear in the middle of
an otherwise mapped inheritance hierarchy (through
<a class="reference internal" href="#single-collection-inheritance"><span class="std std-ref">single collection</span></a> or
<a class="reference internal" href="#collection-per-class-inheritance"><span class="std std-ref">collection per class</span></a>) inheritance.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">A mapped superclass cannot be a document and is not queryable.</p>
</div>
<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="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
<span class="sd">/** @MappedSuperclass */</span>
<span class="k">abstract</span> <span class="k">class</span> <span class="nc">BaseDocument</span>
<span class="p">{</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;mapped-superclass</span> <span class="na">name=</span><span class="s">&quot;Documents\BaseDocument&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;/mapped-superclass&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">Documents\BaseDocument</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">mappedSuperclass</span>
</pre></div>
</div>
</li>
</ul>
</div>
</div>
<div class="section" id="single-collection-inheritance">
<span id="id2"></span><h2>Single Collection Inheritance<a class="headerlink" href="#single-collection-inheritance" title="Permalink to this headline"></a></h2>
<p>In single collection inheritance, each document is stored in a single collection
and a discriminator field is used to distinguish one document type from another.</p>
<p>Simple 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="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
<span class="sd">/**</span>
<span class="sd"> * @Document</span>
<span class="sd"> * @InheritanceType(&quot;SINGLE_COLLECTION&quot;)</span>
<span class="sd"> * @DiscriminatorField(&quot;type&quot;)</span>
<span class="sd"> * @DiscriminatorMap({&quot;person&quot;=&quot;Person&quot;, &quot;employee&quot;=&quot;Employee&quot;})</span>
<span class="sd"> */</span>
<span class="k">class</span> <span class="nc">Person</span>
<span class="p">{</span>
<span class="c1">// ...</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">Employee</span> <span class="k">extends</span> <span class="nx">Person</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\Person&quot;</span> <span class="na">inheritance-type=</span><span class="s">&quot;SINGLE_COLLECTION&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;discriminator-map&gt;</span>
<span class="nt">&lt;discriminator-mapping</span> <span class="na">value=</span><span class="s">&quot;person&quot;</span> <span class="na">class=</span><span class="s">&quot;Person&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;discriminator-mapping</span> <span class="na">value=</span><span class="s">&quot;employee&quot;</span> <span class="na">class=</span><span class="s">&quot;Employee&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/discriminator-map&gt;</span>
<span class="nt">&lt;/document&gt;</span>
<span class="nt">&lt;/doctrine-mongo-mapping&gt;</span>
<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\Employee&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">Documents\Person</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">inheritanceType</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">SINGLE_COLLECTION</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>
<span class="l l-Scalar l-Scalar-Plain">discriminatorMap</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">person</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">Person</span>
<span class="l l-Scalar l-Scalar-Plain">employee</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">Employee</span>
</pre></div>
</div>
</li>
</ul>
</div>
<p>The discriminator value allows Doctrine to infer the class name to instantiate
when hydrating a document. If a discriminator map is used, the discriminator
value will be used to look up the class name in the map.</p>
<p>Now, if we query for a Person and its discriminator value is <code class="docutils literal"><span class="pre">employee</span></code>, we
would get an Employee instance back:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$employee</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Employee</span><span class="p">();</span>
<span class="c1">// ...</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">persist</span><span class="p">(</span><span class="nv">$employee</span><span class="p">);</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">flush</span><span class="p">();</span>
<span class="nv">$employee</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="s1">&#39;Person&#39;</span><span class="p">,</span> <span class="nv">$employee</span><span class="o">-&gt;</span><span class="na">getId</span><span class="p">());</span> <span class="c1">// instanceof Employee</span>
</pre></div>
</div>
<p>Even though we queried for a Person, Doctrine will know to return an Employee
instance because of the discriminator map!</p>
<p>If your document structure has changed and you've added discriminators after
already having a bunch of documents, you can specify a default value for the
discriminator field:</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="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
<span class="sd">/**</span>
<span class="sd"> * @Document</span>
<span class="sd"> * @InheritanceType(&quot;SINGLE_COLLECTION&quot;)</span>
<span class="sd"> * @DiscriminatorField(&quot;type&quot;)</span>
<span class="sd"> * @DiscriminatorMap({&quot;person&quot;=&quot;Person&quot;, &quot;employee&quot;=&quot;Employee&quot;})</span>
<span class="sd"> * @DefaultDiscriminatorValue(&quot;person&quot;)</span>
<span class="sd"> */</span>
<span class="k">class</span> <span class="nc">Person</span>
<span class="p">{</span>
<span class="c1">// ...</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">Employee</span> <span class="k">extends</span> <span class="nx">Person</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\Person&quot;</span> <span class="na">inheritance-type=</span><span class="s">&quot;SINGLE_COLLECTION&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;discriminator-map&gt;</span>
<span class="nt">&lt;discriminator-mapping</span> <span class="na">value=</span><span class="s">&quot;person&quot;</span> <span class="na">class=</span><span class="s">&quot;Person&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;discriminator-mapping</span> <span class="na">value=</span><span class="s">&quot;employee&quot;</span> <span class="na">class=</span><span class="s">&quot;Employee&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;person&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/document&gt;</span>
<span class="nt">&lt;/doctrine-mongo-mapping&gt;</span>
<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\Employee&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">Documents\Person</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">inheritanceType</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">SINGLE_COLLECTION</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>
<span class="l l-Scalar l-Scalar-Plain">defaultDiscriminatorValue</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">person</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">person</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">Person</span>
<span class="l l-Scalar l-Scalar-Plain">employee</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">Employee</span>
</pre></div>
</div>
</li>
</ul>
</div>
</div>
<div class="section" id="collection-per-class-inheritance">
<span id="id3"></span><h2>Collection Per Class Inheritance<a class="headerlink" href="#collection-per-class-inheritance" title="Permalink to this headline"></a></h2>
<p>With collection per class inheritance, each document is stored in its own
collection and contains all inherited fields:</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="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
<span class="sd">/**</span>
<span class="sd"> * @Document</span>
<span class="sd"> * @InheritanceType(&quot;COLLECTION_PER_CLASS&quot;)</span>
<span class="sd"> */</span>
<span class="k">class</span> <span class="nc">Person</span>
<span class="p">{</span>
<span class="c1">// ...</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">Employee</span> <span class="k">extends</span> <span class="nx">Person</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\Person&quot;</span> <span class="na">inheritance-type=</span><span class="s">&quot;COLLECTION_PER_CLASS&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;/document&gt;</span>
<span class="nt">&lt;/doctrine-mongo-mapping&gt;</span>
<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\Employee&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">Documents\Person</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">inheritanceType</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">COLLECTION_PER_CLASS</span>
</pre></div>
</div>
</li>
</ul>
</div>
<p>A discriminator is not needed with this type of inheritance since the data is
separated in different collections.</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="#">Inheritance Mapping</a><ul>
<li><a class="reference internal" href="#mapped-superclasses">Mapped Superclasses</a></li>
<li><a class="reference internal" href="#single-collection-inheritance">Single Collection Inheritance</a></li>
<li><a class="reference internal" href="#collection-per-class-inheritance">Collection Per Class Inheritance</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/inheritance-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>
@@ -0,0 +1,600 @@
<!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>Introduction &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="introduction">
<h1>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline"></a></h1>
<p>Doctrine MongoDB Object Document Mapper is built for PHP 5.3.0+ and
provides transparent persistence for PHP objects to the popular <a class="reference external" href="https://www.mongodb.com/">MongoDB</a> database by <a class="reference external" href="http://www.10gen.com">10gen</a>.</p>
<div class="section" id="features-overview">
<h2>Features Overview<a class="headerlink" href="#features-overview" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li>Transparent persistence.</li>
<li>Map one or many embedded documents.</li>
<li>Map one or many referenced documents.</li>
<li>Create references between documents in different databases.</li>
<li>Map documents with Annotations, XML, YAML or plain old PHP code.</li>
<li>Documents can be stored on the <a class="reference external" href="http://www.php.net/MongoGridFS">MongoGridFS</a>.</li>
<li>Collection per class(concrete) and single collection inheritance supported.</li>
<li>Map your Doctrine 2 ORM Entities to the ODM and use mixed data stores.</li>
<li>Inserts are performed using <a class="reference external" href="http://us.php.net/manual/en/mongocollection.batchinsert.php">MongoCollection::batchInsert()</a></li>
<li>Updates are performed using atomic operators.</li>
</ul>
<p>Here is a quick example of some PHP object documents that demonstrates a few of the features:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">Doctrine\Common\Collections\ArrayCollection</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\Mapping\Annotations</span> <span class="k">as</span> <span class="nx">ODM</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">DateTime</span><span class="p">;</span>
<span class="sd">/** @ODM\MappedSuperclass */</span>
<span class="k">abstract</span> <span class="k">class</span> <span class="nc">BaseEmployee</span>
<span class="p">{</span>
<span class="sd">/** @ODM\Id */</span>
<span class="k">private</span> <span class="nv">$id</span><span class="p">;</span>
<span class="sd">/** @ODM\Field(type=&quot;int&quot;, strategy=&quot;increment&quot;) */</span>
<span class="k">private</span> <span class="nv">$changes</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="sd">/** @ODM\Field(type=&quot;collection&quot;) */</span>
<span class="k">private</span> <span class="nv">$notes</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span>
<span class="sd">/** @ODM\Field(type=&quot;string&quot;) */</span>
<span class="k">private</span> <span class="nv">$name</span><span class="p">;</span>
<span class="sd">/** @ODM\Field(type=&quot;int&quot;) */</span>
<span class="k">private</span> <span class="nv">$salary</span><span class="p">;</span>
<span class="sd">/** @ODM\Field(type=&quot;date&quot;) */</span>
<span class="k">private</span> <span class="nv">$started</span><span class="p">;</span>
<span class="sd">/** @ODM\Field(type=&quot;date&quot;) */</span>
<span class="k">private</span> <span class="nv">$left</span><span class="p">;</span>
<span class="sd">/** @ODM\EmbedOne(targetDocument=&quot;Address&quot;) */</span>
<span class="k">private</span> <span class="nv">$address</span><span class="p">;</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">getId</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">id</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">getChanges</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">changes</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">incrementChanges</span><span class="p">()</span> <span class="p">{</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">changes</span><span class="o">++</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">getNotes</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">notes</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">addNote</span><span class="p">(</span><span class="nv">$note</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">notes</span><span class="p">[]</span> <span class="o">=</span> <span class="nv">$note</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">getName</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">setName</span><span class="p">(</span><span class="nv">$name</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">name</span> <span class="o">=</span> <span class="nv">$name</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">getSalary</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">salary</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">setSalary</span><span class="p">(</span><span class="nv">$salary</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">salary</span> <span class="o">=</span> <span class="p">(</span><span class="nx">int</span><span class="p">)</span> <span class="nv">$salary</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">getStarted</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">started</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">setStarted</span><span class="p">(</span><span class="nx">DateTime</span> <span class="nv">$started</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">started</span> <span class="o">=</span> <span class="nv">$started</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">getLeft</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">left</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">setLeft</span><span class="p">(</span><span class="nx">DateTime</span> <span class="nv">$left</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">left</span> <span class="o">=</span> <span class="nv">$left</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">getAddress</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">address</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">setAddress</span><span class="p">(</span><span class="nx">Address</span> <span class="nv">$address</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">address</span> <span class="o">=</span> <span class="nv">$address</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>
<span class="sd">/** @ODM\Document */</span>
<span class="k">class</span> <span class="nc">Employee</span> <span class="k">extends</span> <span class="nx">BaseEmployee</span>
<span class="p">{</span>
<span class="sd">/** @ODM\ReferenceOne(targetDocument=&quot;Documents\Manager&quot;) */</span>
<span class="k">private</span> <span class="nv">$manager</span><span class="p">;</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">getManager</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">manager</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">setManager</span><span class="p">(</span><span class="nx">Manager</span> <span class="nv">$manager</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">manager</span> <span class="o">=</span> <span class="nv">$manager</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>
<span class="sd">/** @ODM\Document */</span>
<span class="k">class</span> <span class="nc">Manager</span> <span class="k">extends</span> <span class="nx">BaseEmployee</span>
<span class="p">{</span>
<span class="sd">/** @ODM\ReferenceMany(targetDocument=&quot;Documents\Project&quot;) */</span>
<span class="k">private</span> <span class="nv">$projects</span><span class="p">;</span>
<span class="k">public</span> <span class="nx">__construct</span><span class="p">()</span> <span class="p">{</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">projects</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">getProjects</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">projects</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">addProject</span><span class="p">(</span><span class="nx">Project</span> <span class="nv">$project</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">projects</span><span class="p">[]</span> <span class="o">=</span> <span class="nv">$project</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>
<span class="sd">/** @ODM\EmbeddedDocument */</span>
<span class="k">class</span> <span class="nc">Address</span>
<span class="p">{</span>
<span class="sd">/** @ODM\Field(type=&quot;string&quot;) */</span>
<span class="k">private</span> <span class="nv">$address</span><span class="p">;</span>
<span class="sd">/** @ODM\Field(type=&quot;string&quot;) */</span>
<span class="k">private</span> <span class="nv">$city</span><span class="p">;</span>
<span class="sd">/** @ODM\Field(type=&quot;string&quot;) */</span>
<span class="k">private</span> <span class="nv">$state</span><span class="p">;</span>
<span class="sd">/** @ODM\Field(type=&quot;string&quot;) */</span>
<span class="k">private</span> <span class="nv">$zipcode</span><span class="p">;</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">getAddress</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">address</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">setAddress</span><span class="p">(</span><span class="nv">$address</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">address</span> <span class="o">=</span> <span class="nv">$address</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">getCity</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">city</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">setCity</span><span class="p">(</span><span class="nv">$city</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">city</span> <span class="o">=</span> <span class="nv">$city</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">getState</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">state</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">setState</span><span class="p">(</span><span class="nv">$state</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">state</span> <span class="o">=</span> <span class="nv">$state</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">getZipcode</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">zipcode</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">setZipcode</span><span class="p">(</span><span class="nv">$zipcode</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">zipcode</span> <span class="o">=</span> <span class="nv">$zipcode</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>
<span class="sd">/** @ODM\Document */</span>
<span class="k">class</span> <span class="nc">Project</span>
<span class="p">{</span>
<span class="sd">/** @ODM\Id */</span>
<span class="k">private</span> <span class="nv">$id</span><span class="p">;</span>
<span class="sd">/** @ODM\Field(type=&quot;string&quot;) */</span>
<span class="k">private</span> <span class="nv">$name</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="nv">$name</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">name</span> <span class="o">=</span> <span class="nv">$name</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">getId</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">id</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">getName</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">setName</span><span class="p">(</span><span class="nv">$name</span><span class="p">)</span> <span class="p">{</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">name</span> <span class="o">=</span> <span class="nv">$name</span><span class="p">;</span> <span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Now those objects can be used just like you weren't using any
persistence layer at all and can be persisted transparently by
Doctrine:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">Documents\Employee</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Documents\Address</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Documents\Project</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Documents\Manager</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">DateTime</span><span class="p">;</span>
<span class="nv">$employee</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Employee</span><span class="p">();</span>
<span class="nv">$employee</span><span class="o">-&gt;</span><span class="na">setName</span><span class="p">(</span><span class="s1">&#39;Employee&#39;</span><span class="p">);</span>
<span class="nv">$employee</span><span class="o">-&gt;</span><span class="na">setSalary</span><span class="p">(</span><span class="mi">50000</span><span class="p">);</span>
<span class="nv">$employee</span><span class="o">-&gt;</span><span class="na">setStarted</span><span class="p">(</span><span class="k">new</span> <span class="nx">DateTime</span><span class="p">());</span>
<span class="nv">$address</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Address</span><span class="p">();</span>
<span class="nv">$address</span><span class="o">-&gt;</span><span class="na">setAddress</span><span class="p">(</span><span class="s1">&#39;555 Doctrine Rd.&#39;</span><span class="p">);</span>
<span class="nv">$address</span><span class="o">-&gt;</span><span class="na">setCity</span><span class="p">(</span><span class="s1">&#39;Nashville&#39;</span><span class="p">);</span>
<span class="nv">$address</span><span class="o">-&gt;</span><span class="na">setState</span><span class="p">(</span><span class="s1">&#39;TN&#39;</span><span class="p">);</span>
<span class="nv">$address</span><span class="o">-&gt;</span><span class="na">setZipcode</span><span class="p">(</span><span class="s1">&#39;37209&#39;</span><span class="p">);</span>
<span class="nv">$employee</span><span class="o">-&gt;</span><span class="na">setAddress</span><span class="p">(</span><span class="nv">$address</span><span class="p">);</span>
<span class="nv">$project</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Project</span><span class="p">(</span><span class="s1">&#39;New Project&#39;</span><span class="p">);</span>
<span class="nv">$manager</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Manager</span><span class="p">();</span>
<span class="nv">$manager</span><span class="o">-&gt;</span><span class="na">setName</span><span class="p">(</span><span class="s1">&#39;Manager&#39;</span><span class="p">);</span>
<span class="nv">$manager</span><span class="o">-&gt;</span><span class="na">setSalary</span><span class="p">(</span><span class="mi">100000</span><span class="p">);</span>
<span class="nv">$manager</span><span class="o">-&gt;</span><span class="na">setStarted</span><span class="p">(</span><span class="k">new</span> <span class="nx">DateTime</span><span class="p">());</span>
<span class="nv">$manager</span><span class="o">-&gt;</span><span class="na">addProject</span><span class="p">(</span><span class="nv">$project</span><span class="p">);</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">persist</span><span class="p">(</span><span class="nv">$employee</span><span class="p">);</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">persist</span><span class="p">(</span><span class="nv">$address</span><span class="p">);</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">persist</span><span class="p">(</span><span class="nv">$project</span><span class="p">);</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">persist</span><span class="p">(</span><span class="nv">$manager</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>The above would insert the following:</p>
<div class="highlight-default"><div class="highlight"><pre>Array
(
[000000004b0a33690000000001c304c6] =&gt; Array
(
[name] =&gt; New Project
)
)
Array
(
[000000004b0a33660000000001c304c6] =&gt; Array
(
[changes] =&gt; 0
[notes] =&gt; Array
(
)
[name] =&gt; Manager
[salary] =&gt; 100000
[started] =&gt; MongoDate Object
(
[sec] =&gt; 1275265048
[usec] =&gt; 0
)
[projects] =&gt; Array
(
[0] =&gt; Array
(
[$ref] =&gt; projects
[$id] =&gt; 4c0300188ead0e947a000000
[$db] =&gt; my_db
)
)
)
)
Array
(
[000000004b0a336a0000000001c304c6] =&gt; Array
(
[changes] =&gt; 0
[notes] =&gt; Array
(
)
[name] =&gt; Employee
[salary] =&gt; 50000
[started] =&gt; MongoDate Object
(
[sec] =&gt; 1275265048
[usec] =&gt; 0
)
[address] =&gt; Array
(
[address] =&gt; 555 Doctrine Rd.
[city] =&gt; Nashville
[state] =&gt; TN
[zipcode] =&gt; 37209
)
)
)
</pre></div>
</div>
<p>If we update a property and call <code class="docutils literal"><span class="pre">-&gt;flush()</span></code> again we'll get an
efficient update query using the atomic operators:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$newProject</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Project</span><span class="p">(</span><span class="s1">&#39;Another Project&#39;</span><span class="p">);</span>
<span class="nv">$manager</span><span class="o">-&gt;</span><span class="na">setSalary</span><span class="p">(</span><span class="mi">200000</span><span class="p">);</span>
<span class="nv">$manager</span><span class="o">-&gt;</span><span class="na">addNote</span><span class="p">(</span><span class="s1">&#39;Gave user 100k a year raise&#39;</span><span class="p">);</span>
<span class="nv">$manager</span><span class="o">-&gt;</span><span class="na">incrementChanges</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>
<span class="nv">$manager</span><span class="o">-&gt;</span><span class="na">addProject</span><span class="p">(</span><span class="nv">$newProject</span><span class="p">);</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">persist</span><span class="p">(</span><span class="nv">$newProject</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>The above could would produce an update that looks something like
this:</p>
<div class="highlight-default"><div class="highlight"><pre>Array
(
[$inc] =&gt; Array
(
[changes] =&gt; 2
)
[$pushAll] =&gt; Array
(
[notes] =&gt; Array
(
[0] =&gt; Gave user 100k a year raise
)
[projects] =&gt; Array
(
[0] =&gt; Array
(
[$ref] =&gt; projects
[$id] =&gt; 4c0310718ead0e767e030000
[$db] =&gt; my_db
)
)
)
[$set] =&gt; Array
(
[salary] =&gt; 200000
)
)
</pre></div>
</div>
<p>This is a simple example, but it demonstrates well that you can
transparently persist PHP objects while still utilizing the
atomic operators for updating documents! Continue reading to learn
how to get the Doctrine MongoDB Object Document Mapper setup and
running!</p>
</div>
<div class="section" id="setup">
<h2>Setup<a class="headerlink" href="#setup" title="Permalink to this headline"></a></h2>
<p>Before we can begin, we'll need to install the Doctrine MongoDB ODM library and
its dependencies. The easiest way to do this is with <a class="reference external" href="http://getcomposer.org/">Composer</a>:</p>
<div class="highlight-default"><div class="highlight"><pre>$ composer require &quot;doctrine/mongodb-odm&quot;
</pre></div>
</div>
<p>Once ODM and its dependencies have been downloaded, we can begin by creating a
<code class="docutils literal"><span class="pre">bootstrap.php</span></code> file in our project's root directory, where Composer's
<code class="docutils literal"><span class="pre">vendor/</span></code> directory also resides. Let's start by importing some of the classes
we'll use:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">Doctrine\MongoDB\Connection</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\Configuration</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\DocumentManager</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver</span><span class="p">;</span>
</pre></div>
</div>
<p>The first bit of code will be to import Composer's autoloader, so these classes
can actually be loaded:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="c1">// ...</span>
<span class="k">if</span> <span class="p">(</span> <span class="o">!</span> <span class="nb">file_exists</span><span class="p">(</span><span class="nv">$file</span> <span class="o">=</span> <span class="nx">__DIR__</span><span class="o">.</span><span class="s1">&#39;/vendor/autoload.php&#39;</span><span class="p">))</span> <span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nx">RuntimeException</span><span class="p">(</span><span class="s1">&#39;Install dependencies to run this script.&#39;</span><span class="p">);</span>
<span class="p">}</span>
<span class="nv">$loader</span> <span class="o">=</span> <span class="k">require_once</span> <span class="nv">$file</span><span class="p">;</span>
</pre></div>
</div>
<p>Note that instead of simply requiring the file, we assign its return value to
the <code class="docutils literal"><span class="pre">$loader</span></code> variable. Assuming document classes will be stored in the
<code class="docutils literal"><span class="pre">Documents/</span></code> directory (with a namespace to match), we can register them with
the autoloader like so:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="c1">// ...</span>
<span class="nv">$loader</span><span class="o">-&gt;</span><span class="na">add</span><span class="p">(</span><span class="s1">&#39;Documents&#39;</span><span class="p">,</span> <span class="nx">__DIR__</span><span class="p">);</span>
</pre></div>
</div>
<p>Ultimately, our application will utilize ODM through its <code class="docutils literal"><span class="pre">DocumentManager</span></code>
class. Before we can instantiate a <code class="docutils literal"><span class="pre">DocumentManager</span></code>, we need to construct the
<code class="docutils literal"><span class="pre">Connection</span></code> and <code class="docutils literal"><span class="pre">Configuration</span></code> objects required by its factory method:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="c1">// ...</span>
<span class="nv">$connection</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Connection</span><span class="p">();</span>
<span class="nv">$config</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Configuration</span><span class="p">();</span>
</pre></div>
</div>
<p>Next, we'll specify some essential configuration options. The following assumes
that we will store generated proxy and hydrator classes in the <code class="docutils literal"><span class="pre">Proxies/</span></code> and
<code class="docutils literal"><span class="pre">Hydrators/</span></code> directories, respectively. Additionally, we'll define a default
database name to use for document classes that do not specify a database in
their mapping.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="c1">// ...</span>
<span class="nv">$config</span><span class="o">-&gt;</span><span class="na">setProxyDir</span><span class="p">(</span><span class="nx">__DIR__</span> <span class="o">.</span> <span class="s1">&#39;/Proxies&#39;</span><span class="p">);</span>
<span class="nv">$config</span><span class="o">-&gt;</span><span class="na">setProxyNamespace</span><span class="p">(</span><span class="s1">&#39;Proxies&#39;</span><span class="p">);</span>
<span class="nv">$config</span><span class="o">-&gt;</span><span class="na">setHydratorDir</span><span class="p">(</span><span class="nx">__DIR__</span> <span class="o">.</span> <span class="s1">&#39;/Hydrators&#39;</span><span class="p">);</span>
<span class="nv">$config</span><span class="o">-&gt;</span><span class="na">setHydratorNamespace</span><span class="p">(</span><span class="s1">&#39;Hydrators&#39;</span><span class="p">);</span>
<span class="nv">$config</span><span class="o">-&gt;</span><span class="na">setDefaultDB</span><span class="p">(</span><span class="s1">&#39;doctrine_odm&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>The easiest way to define mappings for our document classes is with annotations.
We'll need to specify an annotation driver in our configuration (with one or
more paths) and register the annotations for the driver:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="c1">// ...</span>
<span class="nv">$config</span><span class="o">-&gt;</span><span class="na">setMetadataDriverImpl</span><span class="p">(</span><span class="nx">AnnotationDriver</span><span class="o">::</span><span class="na">create</span><span class="p">(</span><span class="nx">__DIR__</span> <span class="o">.</span> <span class="s1">&#39;/Documents&#39;</span><span class="p">));</span>
<span class="nx">AnnotationDriver</span><span class="o">::</span><span class="na">registerAnnotationClasses</span><span class="p">();</span>
</pre></div>
</div>
<p>At this point, we have everything necessary to construct a <code class="docutils literal"><span class="pre">DocumentManager</span></code>:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="c1">// ...</span>
<span class="nv">$dm</span> <span class="o">=</span> <span class="nx">DocumentManager</span><span class="o">::</span><span class="na">create</span><span class="p">(</span><span class="nv">$connection</span><span class="p">,</span> <span class="nv">$config</span><span class="p">);</span>
</pre></div>
</div>
<p>The final <code class="docutils literal"><span class="pre">bootstrap.php</span></code> file should look like this:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">Doctrine\MongoDB\Connection</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\Configuration</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\DocumentManager</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span> <span class="o">!</span> <span class="nb">file_exists</span><span class="p">(</span><span class="nv">$file</span> <span class="o">=</span> <span class="nx">__DIR__</span><span class="o">.</span><span class="s1">&#39;/vendor/autoload.php&#39;</span><span class="p">))</span> <span class="p">{</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nx">RuntimeException</span><span class="p">(</span><span class="s1">&#39;Install dependencies to run this script.&#39;</span><span class="p">);</span>
<span class="p">}</span>
<span class="nv">$loader</span> <span class="o">=</span> <span class="k">require_once</span> <span class="nv">$file</span><span class="p">;</span>
<span class="nv">$loader</span><span class="o">-&gt;</span><span class="na">add</span><span class="p">(</span><span class="s1">&#39;Documents&#39;</span><span class="p">,</span> <span class="nx">__DIR__</span><span class="p">);</span>
<span class="nv">$connection</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Connection</span><span class="p">();</span>
<span class="nv">$config</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Configuration</span><span class="p">();</span>
<span class="nv">$config</span><span class="o">-&gt;</span><span class="na">setProxyDir</span><span class="p">(</span><span class="nx">__DIR__</span> <span class="o">.</span> <span class="s1">&#39;/Proxies&#39;</span><span class="p">);</span>
<span class="nv">$config</span><span class="o">-&gt;</span><span class="na">setProxyNamespace</span><span class="p">(</span><span class="s1">&#39;Proxies&#39;</span><span class="p">);</span>
<span class="nv">$config</span><span class="o">-&gt;</span><span class="na">setHydratorDir</span><span class="p">(</span><span class="nx">__DIR__</span> <span class="o">.</span> <span class="s1">&#39;/Hydrators&#39;</span><span class="p">);</span>
<span class="nv">$config</span><span class="o">-&gt;</span><span class="na">setHydratorNamespace</span><span class="p">(</span><span class="s1">&#39;Hydrators&#39;</span><span class="p">);</span>
<span class="nv">$config</span><span class="o">-&gt;</span><span class="na">setDefaultDB</span><span class="p">(</span><span class="s1">&#39;doctrine_odm&#39;</span><span class="p">);</span>
<span class="nv">$config</span><span class="o">-&gt;</span><span class="na">setMetadataDriverImpl</span><span class="p">(</span><span class="nx">AnnotationDriver</span><span class="o">::</span><span class="na">create</span><span class="p">(</span><span class="nx">__DIR__</span> <span class="o">.</span> <span class="s1">&#39;/Documents&#39;</span><span class="p">));</span>
<span class="nx">AnnotationDriver</span><span class="o">::</span><span class="na">registerAnnotationClasses</span><span class="p">();</span>
<span class="nv">$dm</span> <span class="o">=</span> <span class="nx">DocumentManager</span><span class="o">::</span><span class="na">create</span><span class="p">(</span><span class="nv">$connection</span><span class="p">,</span> <span class="nv">$config</span><span class="p">);</span>
</pre></div>
</div>
<p>That is it! Your <code class="docutils literal"><span class="pre">DocumentManager</span></code> instance is ready to be used!</p>
</div>
<div class="section" id="using-php-7">
<h2>Using PHP 7<a class="headerlink" href="#using-php-7" title="Permalink to this headline"></a></h2>
<p>You can use Doctrine MongoDB ODM with PHP 7, but there are a few extra steps during
the installation. Since the legacy driver (referred to as <code class="docutils literal"><span class="pre">ext-mongo</span></code>) is not
available on PHP 7, you will need the new driver (<code class="docutils literal"><span class="pre">ext-mongodb</span></code>) installed and
use a polyfill to provide the API of the legacy driver.</p>
<p>To do this, you have to require <code class="docutils literal"><span class="pre">alcaeus/mongo-php-adapter</span></code> before adding a composer
dependency to ODM. To do this, run the following command:</p>
<div class="highlight-default"><div class="highlight"><pre>$ composer require &quot;alcaeus/mongo-php-adapter&quot;
</pre></div>
</div>
<p>Next, manually add a <code class="docutils literal"><span class="pre">provide</span></code> section to your <code class="docutils literal"><span class="pre">composer.json</span></code>:</p>
<div class="highlight-json"><div class="highlight"><pre>&quot;provide&quot;: {
&quot;ext-mongo&quot;: &quot;1.6.14&quot;
}
</pre></div>
</div>
<p>This section needs to be added to work around a composer issue with libraries
providing platform packages (such as <code class="docutils literal"><span class="pre">ext-mongo</span></code>). Now, you may install ODM as
described above:</p>
<div class="highlight-default"><div class="highlight"><pre>$ composer require &quot;doctrine/mongodb-odm&quot;
</pre></div>
</div>
</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="#">Introduction</a><ul>
<li><a class="reference internal" href="#features-overview">Features Overview</a></li>
<li><a class="reference internal" href="#setup">Setup</a></li>
<li><a class="reference internal" href="#using-php-7">Using PHP 7</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/introduction.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>
@@ -0,0 +1,163 @@
<!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>Logging &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="logging">
<h1>Logging<a class="headerlink" href="#logging" title="Permalink to this headline"></a></h1>
<p>If you want to turn on logging and receive information about
queries made to the database you can do so on your
<code class="docutils literal"><span class="pre">Doctrine\ODM\MongoDB\Configuration</span></code> instance:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="c1">// ...</span>
<span class="nv">$config</span><span class="o">-&gt;</span><span class="na">setLoggerCallable</span><span class="p">(</span><span class="k">function</span><span class="p">(</span><span class="k">array</span> <span class="nv">$log</span><span class="p">)</span> <span class="p">{</span>
<span class="nb">print_r</span><span class="p">(</span><span class="nv">$log</span><span class="p">);</span>
<span class="p">});</span>
</pre></div>
</div>
<p>You can register any PHP callable and it will be notified with a
single argument that is an array of information about the query
being sent to the database.</p>
<p>Just like the anonymous function above, you could pass an array
with a object instance and a method to call:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="c1">// ...</span>
<span class="nv">$config</span><span class="o">-&gt;</span><span class="na">setLoggerCallable</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="nv">$obj</span><span class="p">,</span> <span class="s1">&#39;method&#39;</span><span class="p">));</span>
</pre></div>
</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>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/logging.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>
@@ -0,0 +1,242 @@
<!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>Map Reduce &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="map-reduce">
<h1>Map Reduce<a class="headerlink" href="#map-reduce" title="Permalink to this headline"></a></h1>
<p>The Doctrine MongoDB ODM fully supports the <a class="reference external" href="https://docs.mongodb.com/manual/core/map-reduce/">map reduce</a> functionality via its
<a class="reference internal" href="query-builder-api.html"><span class="doc">Query Builder API</span></a>.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p>From the MongoDB manual:</p>
<p class="last">Map-reduce is a data processing paradigm for condensing large volumes of
data into useful aggregated results. In MongoDB, map-reduce operations use
custom JavaScript functions to map, or associate, values to a key. If a key
has multiple values mapped to it, the operation reduces the values for the
key to a single object.</p>
</div>
<p>Imagine a situation where you had an application with a document
named <code class="docutils literal"><span class="pre">Event</span></code> and it was related to a <code class="docutils literal"><span class="pre">User</span></code> document:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
<span class="sd">/** @Document */</span>
<span class="k">class</span> <span class="nc">Event</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;Documents\User&quot;) */</span>
<span class="k">private</span> <span class="nv">$user</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">private</span> <span class="nv">$type</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;date&quot;) */</span>
<span class="k">private</span> <span class="nv">$date</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">private</span> <span class="nv">$description</span><span class="p">;</span>
<span class="c1">// getters and setters</span>
<span class="p">}</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="p">}</span>
</pre></div>
</div>
<p>We may have a situation where we want to run a query that tells us how many
sales events each user has had. We can easily use the map reduce functionality
of MongoDB via the ODM's query builder. Here is a simple map reduce example:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$qb</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;Documents\User&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;type&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">equals</span><span class="p">(</span><span class="s1">&#39;sale&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">map</span><span class="p">(</span><span class="s1">&#39;function() { emit(this.user.$id, 1); }&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">reduce</span><span class="p">(</span><span class="s1">&#39;function(k, vals) {</span>
<span class="s1"> var sum = 0;</span>
<span class="s1"> for (var i in vals) {</span>
<span class="s1"> sum += vals[i];</span>
<span class="s1"> }</span>
<span class="s1"> return sum;</span>
<span class="s1"> }&#39;</span><span class="p">);</span>
<span class="nv">$query</span> <span class="o">=</span> <span class="nv">$qb</span><span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">();</span>
<span class="nv">$results</span> <span class="o">=</span> <span class="nv">$query</span><span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$results</span> <span class="k">as</span> <span class="nv">$user</span><span class="p">)</span> <span class="p">{</span>
<span class="nb">printf</span><span class="p">(</span><span class="s2">&quot;User %s had %d sale(s).</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="nv">$user</span><span class="p">[</span><span class="s1">&#39;_id&#39;</span><span class="p">],</span> <span class="nv">$user</span><span class="p">[</span><span class="s1">&#39;value&#39;</span><span class="p">]);</span>
<span class="p">}</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">The query builder also has a <code class="docutils literal"><span class="pre">finalize()</span></code> method, which may be used to
specify a <a class="reference external" href="https://docs.mongodb.com/master/reference/command/mapReduce/#mapreduce-finalize-cmd">finalize function</a> to be executed after the reduce step.</p>
</div>
<p>When using map reduce with Doctrine, the results are not hydrated into objects.
Instead, the raw results are returned directly from MongoDB.</p>
<p>The preceding example is equivalent to executing the following command via the
PHP driver directly:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$db</span> <span class="o">=</span> <span class="nv">$mongoClient</span><span class="o">-&gt;</span><span class="na">selectDB</span><span class="p">(</span><span class="s1">&#39;my_db&#39;</span><span class="p">);</span>
<span class="nv">$map</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MongoCode</span><span class="p">(</span><span class="s1">&#39;function() { emit(this.user.$id, 1); }&#39;</span><span class="p">);</span>
<span class="nv">$reduce</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MongoCode</span><span class="p">(</span><span class="s1">&#39;function(k, vals) {</span>
<span class="s1"> var sum = 0;</span>
<span class="s1"> for (var i in vals) {</span>
<span class="s1"> sum += vals[i];</span>
<span class="s1"> }</span>
<span class="s1"> return sum;</span>
<span class="s1">}&#39;</span><span class="p">);</span>
<span class="nv">$result</span> <span class="o">=</span> <span class="nv">$db</span><span class="o">-&gt;</span><span class="na">command</span><span class="p">(</span><span class="k">array</span><span class="p">(</span>
<span class="s1">&#39;mapreduce&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;events&#39;</span><span class="p">,</span>
<span class="s1">&#39;map&#39;</span> <span class="o">=&gt;</span> <span class="nv">$map</span><span class="p">,</span>
<span class="s1">&#39;reduce&#39;</span> <span class="o">=&gt;</span> <span class="nv">$reduce</span><span class="p">,</span>
<span class="s1">&#39;query&#39;</span> <span class="o">=&gt;</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;type&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;sale&#39;</span><span class="p">),</span>
<span class="p">));</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$result</span><span class="p">[</span><span class="s1">&#39;results&#39;</span><span class="p">]</span> <span class="k">as</span> <span class="nv">$user</span><span class="p">)</span> <span class="p">{</span>
<span class="nb">printf</span><span class="p">(</span><span class="s2">&quot;User %s had %d sale(s).</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span> <span class="nv">$user</span><span class="p">[</span><span class="s1">&#39;_id&#39;</span><span class="p">],</span> <span class="nv">$user</span><span class="p">[</span><span class="s1">&#39;value&#39;</span><span class="p">]);</span>
<span class="p">}</span>
</pre></div>
</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>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/map-reduce.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>
@@ -0,0 +1,326 @@
<!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>Metadata Drivers &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="metadata-drivers">
<h1>Metadata Drivers<a class="headerlink" href="#metadata-drivers" title="Permalink to this headline"></a></h1>
<p>The heart of an object mapper is the mapping information
that glues everything together. It instructs the DocumentManager how
it should behave when dealing with the different documents.</p>
<div class="section" id="core-metadata-drivers">
<h2>Core Metadata Drivers<a class="headerlink" href="#core-metadata-drivers" title="Permalink to this headline"></a></h2>
<p>Doctrine provides a few different ways for you to specify your
metadata:</p>
<ul class="simple">
<li><strong>XML files</strong> (XmlDriver)</li>
<li><strong>Class DocBlock Annotations</strong> (AnnotationDriver)</li>
<li><strong>YAML files</strong> (YamlDriver)</li>
<li><strong>PHP Code in files or static functions</strong> (PhpDriver)</li>
</ul>
<p>Something important to note about the above drivers is they are all
an intermediate step to the same end result. The mapping
information is populated to <code class="docutils literal"><span class="pre">Doctrine\ODM\MongoDB\Mapping\ClassMetadata</span></code>
instances. So in the end, Doctrine only ever has to work with the
API of the <code class="docutils literal"><span class="pre">ClassMetadata</span></code> class to get mapping information for
a document.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p>The populated <code class="docutils literal"><span class="pre">ClassMetadata</span></code> instances are also cached
so in a production environment the parsing and populating only ever
happens once. You can configure the metadata cache implementation
using the <code class="docutils literal"><span class="pre">setMetadataCacheImpl()</span></code> method on the
<code class="docutils literal"><span class="pre">Doctrine\ODM\MongoDB\Configuration</span></code> class:</p>
<div class="last highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$em</span><span class="o">-&gt;</span><span class="na">getConfiguration</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">setMetadataCacheImpl</span><span class="p">(</span><span class="k">new</span> <span class="nx">ApcCache</span><span class="p">());</span>
</pre></div>
</div>
</div>
<p>If you want to use one of the included core metadata drivers you
just need to configure it. All the drivers are in the
<code class="docutils literal"><span class="pre">Doctrine\ODM\MongoDB\Mapping\Driver</span></code> namespace:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$driver</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">\Doctrine\ODM\MongoDB\Mapping\Driver\XmlDriver</span><span class="p">(</span><span class="s1">&#39;/path/to/mapping/files&#39;</span><span class="p">);</span>
<span class="nv">$em</span><span class="o">-&gt;</span><span class="na">getConfiguration</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">setMetadataDriverImpl</span><span class="p">(</span><span class="nv">$driver</span><span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="implementing-metadata-drivers">
<h2>Implementing Metadata Drivers<a class="headerlink" href="#implementing-metadata-drivers" title="Permalink to this headline"></a></h2>
<p>In addition to the included metadata drivers you can very easily
implement your own. All you need to do is define a class which
implements the <code class="docutils literal"><span class="pre">Driver</span></code> interface:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">namespace</span> <span class="nx">Doctrine\ODM\MongoDB\Mapping\Driver</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\Mapping\ClassMetadataInfo</span><span class="p">;</span>
<span class="k">interface</span> <span class="nx">Driver</span>
<span class="p">{</span>
<span class="sd">/**</span>
<span class="sd"> * Loads the metadata for the specified class into the provided container.</span>
<span class="sd"> *</span>
<span class="sd"> * @param string $className</span>
<span class="sd"> * @param ClassMetadataInfo $metadata</span>
<span class="sd"> */</span>
<span class="k">function</span> <span class="nf">loadMetadataForClass</span><span class="p">(</span><span class="nv">$className</span><span class="p">,</span> <span class="nx">ClassMetadataInfo</span> <span class="nv">$metadata</span><span class="p">);</span>
<span class="sd">/**</span>
<span class="sd"> * Gets the names of all mapped classes known to this driver.</span>
<span class="sd"> *</span>
<span class="sd"> * @return array The names of all mapped classes known to this driver.</span>
<span class="sd"> */</span>
<span class="k">function</span> <span class="nf">getAllClassNames</span><span class="p">();</span>
<span class="sd">/**</span>
<span class="sd"> * Whether the class with the specified name should have its metadata loaded.</span>
<span class="sd"> * This is only the case if it is either mapped as a Document or a</span>
<span class="sd"> * MappedSuperclass.</span>
<span class="sd"> *</span>
<span class="sd"> * @param string $className</span>
<span class="sd"> * @return boolean</span>
<span class="sd"> */</span>
<span class="k">function</span> <span class="nf">isTransient</span><span class="p">(</span><span class="nv">$className</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<p>If you want to write a metadata driver to parse information from
some file format we've made your life a little easier by providing
the <code class="docutils literal"><span class="pre">AbstractFileDriver</span></code> implementation for you to extend from:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">class</span> <span class="nc">MyMetadataDriver</span> <span class="k">extends</span> <span class="nx">AbstractFileDriver</span>
<span class="p">{</span>
<span class="sd">/**</span>
<span class="sd"> * {@inheritdoc}</span>
<span class="sd"> */</span>
<span class="k">protected</span> <span class="nv">$_fileExtension</span> <span class="o">=</span> <span class="s1">&#39;.dcm.ext&#39;</span><span class="p">;</span>
<span class="sd">/**</span>
<span class="sd"> * {@inheritdoc}</span>
<span class="sd"> */</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">loadMetadataForClass</span><span class="p">(</span><span class="nv">$className</span><span class="p">,</span> <span class="nx">ClassMetadataInfo</span> <span class="nv">$metadata</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$data</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">_loadMappingFile</span><span class="p">(</span><span class="nv">$file</span><span class="p">);</span>
<span class="c1">// populate ClassMetadataInfo instance from $data</span>
<span class="p">}</span>
<span class="sd">/**</span>
<span class="sd"> * {@inheritdoc}</span>
<span class="sd"> */</span>
<span class="k">protected</span> <span class="k">function</span> <span class="nf">_loadMappingFile</span><span class="p">(</span><span class="nv">$file</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">// parse contents of $file and return php data structure</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">When using the <code class="docutils literal"><span class="pre">AbstractFileDriver</span></code> it requires that you
only have one document defined per file and the file named after the
class described inside where namespace separators are replaced by
periods. So if you have a document named <code class="docutils literal"><span class="pre">Documents\User</span></code> and you
wanted to write a mapping file for your driver above you would need
to name the file <code class="docutils literal"><span class="pre">Documents.User.dcm.ext</span></code> for it to be
recognized.</p>
</div>
<p>Now you can use your <code class="docutils literal"><span class="pre">MyMetadataDriver</span></code> implementation by setting
it with the <code class="docutils literal"><span class="pre">setMetadataDriverImpl()</span></code> method:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$driver</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">MyMetadataDriver</span><span class="p">(</span><span class="s1">&#39;/path/to/mapping/files&#39;</span><span class="p">);</span>
<span class="nv">$em</span><span class="o">-&gt;</span><span class="na">getConfiguration</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">setMetadataDriverImpl</span><span class="p">(</span><span class="nv">$driver</span><span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="classmetadata">
<h2>ClassMetadata<a class="headerlink" href="#classmetadata" title="Permalink to this headline"></a></h2>
<p>The last piece you need to know and understand about metadata in
Doctrine is the API of the <code class="docutils literal"><span class="pre">ClassMetadata</span></code> classes. You need to
be familiar with them in order to implement your own drivers but
more importantly to retrieve mapping information for a certain
document when needed.</p>
<p>You have all the methods you need to manually specify the mapping
information instead of using some mapping file to populate it from.
The base <code class="docutils literal"><span class="pre">ClassMetadataInfo</span></code> class is responsible for only data
storage and is not meant for runtime use. It does not require that
the class actually exists yet so it is useful for describing some
document before it exists and using that information to generate for
example the documents themselves. The class <code class="docutils literal"><span class="pre">ClassMetadata</span></code>
extends <code class="docutils literal"><span class="pre">ClassMetadataInfo</span></code> and adds some functionality required
for runtime usage and requires that the PHP class is present and
can be autoloaded.</p>
<p>You can read more about the API of the <code class="docutils literal"><span class="pre">ClassMetadata</span></code> classes in
the PHP Mapping chapter.</p>
</div>
<div class="section" id="getting-classmetadata-instances">
<h2>Getting ClassMetadata Instances<a class="headerlink" href="#getting-classmetadata-instances" title="Permalink to this headline"></a></h2>
<p>If you want to get the <code class="docutils literal"><span class="pre">ClassMetadata</span></code> instance for a document in
your project to programmatically use some mapping information to
generate some HTML or something similar you can retrieve it through
the <code class="docutils literal"><span class="pre">ClassMetadataFactory</span></code>:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$cmf</span> <span class="o">=</span> <span class="nv">$em</span><span class="o">-&gt;</span><span class="na">getMetadataFactory</span><span class="p">();</span>
<span class="nv">$class</span> <span class="o">=</span> <span class="nv">$cmf</span><span class="o">-&gt;</span><span class="na">getMetadataFor</span><span class="p">(</span><span class="s1">&#39;MyDocumentName&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>Now you can learn about the document and use the data stored in the
<code class="docutils literal"><span class="pre">ClassMetadata</span></code> instance to get all mapped fields for example and
iterate over them:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$class</span><span class="o">-&gt;</span><span class="na">fieldMappings</span> <span class="k">as</span> <span class="nv">$fieldMapping</span><span class="p">)</span> <span class="p">{</span>
<span class="k">echo</span> <span class="nv">$fieldMapping</span><span class="p">[</span><span class="s1">&#39;fieldName&#39;</span><span class="p">]</span> <span class="o">.</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
</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="#">Metadata Drivers</a><ul>
<li><a class="reference internal" href="#core-metadata-drivers">Core Metadata Drivers</a></li>
<li><a class="reference internal" href="#implementing-metadata-drivers">Implementing Metadata Drivers</a></li>
<li><a class="reference internal" href="#classmetadata">ClassMetadata</a></li>
<li><a class="reference internal" href="#getting-classmetadata-instances">Getting ClassMetadata Instances</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/metadata-drivers.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>
@@ -0,0 +1,343 @@
<!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>Migrating Schemas &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="migrating-schemas">
<h1>Migrating Schemas<a class="headerlink" href="#migrating-schemas" title="Permalink to this headline"></a></h1>
<p>Even though MongoDB is schemaless, introducing some kind of object mapper means
that your object definitions become your schema. You may have a situation where
you rename a property in your object model but need to load values from older
documents where the field is still using the former name. While you could use
MongoDB's <a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/update/rename/">$rename</a> operator to migrate everything, sometimes a lazy migration
is preferable. Doctrine offers a few different methods for dealing with this
problem!</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">The features in this chapter were inspired by <a class="reference external" href="https://github.com/objectify/objectify">Objectify</a>, an object mapper
for the Google App Engine datastore. Additional information may be found in
the <a class="reference external" href="https://github.com/objectify/objectify/wiki/SchemaMigration">Objectify schema migration</a> documentation.</p>
</div>
<div class="section" id="renaming-a-field">
<h2>Renaming a Field<a class="headerlink" href="#renaming-a-field" title="Permalink to this headline"></a></h2>
<p>Let's say you have a simple document that starts off with the following fields:</p>
<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">Person</span>
<span class="p">{</span>
<span class="sd">/** @Id */</span>
<span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">public</span> <span class="nv">$name</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Later on, you need rename <code class="docutils literal"><span class="pre">name</span></code> to <code class="docutils literal"><span class="pre">fullName</span></code>; however, you'd like to
hydrate <code class="docutils literal"><span class="pre">fullName</span></code> from <code class="docutils literal"><span class="pre">name</span></code> if the new field doesn't exist.</p>
<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">Person</span>
<span class="p">{</span>
<span class="sd">/** @Id */</span>
<span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) @AlsoLoad(&quot;name&quot;) */</span>
<span class="k">public</span> <span class="nv">$fullName</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>When a Person is loaded, the <code class="docutils literal"><span class="pre">fullName</span></code> field will be populated with the value
of <code class="docutils literal"><span class="pre">name</span></code> if <code class="docutils literal"><span class="pre">fullName</span></code> is not found. When the Person is persisted, this
value will then be stored in the <code class="docutils literal"><span class="pre">fullName</span></code> field.</p>
<div class="admonition caution">
<p class="first admonition-title">Caution</p>
<p class="last">A caveat of this feature is that it only affects hydration. Queries will not
know about the rename, so a query on <code class="docutils literal"><span class="pre">fullName</span></code> will only match documents
with the new field name. You can still query using the <code class="docutils literal"><span class="pre">name</span></code> field to
find older documents. The <a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/query/or/">$or</a> query operator could be used to match both.</p>
</div>
</div>
<div class="section" id="transforming-data">
<h2>Transforming Data<a class="headerlink" href="#transforming-data" title="Permalink to this headline"></a></h2>
<p>You may have a situation where you want to migrate a Person's name to separate
<code class="docutils literal"><span class="pre">firstName</span></code> and <code class="docutils literal"><span class="pre">lastName</span></code> fields. This is also possible by specifying the
<code class="docutils literal"><span class="pre">&#64;AlsoLoad</span></code> annotation on a method, which will then be invoked immediately
before normal hydration.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/** @Document @HasLifecycleCallbacks */</span>
<span class="k">class</span> <span class="nc">Person</span>
<span class="p">{</span>
<span class="sd">/** @Id */</span>
<span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">public</span> <span class="nv">$firstName</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">public</span> <span class="nv">$lastName</span><span class="p">;</span>
<span class="sd">/** @AlsoLoad({&quot;name&quot;, &quot;fullName&quot;}) */</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">populateFirstAndLastName</span><span class="p">(</span><span class="nv">$fullName</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">list</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">firstName</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">lastName</span><span class="p">)</span> <span class="o">=</span> <span class="nb">explode</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">,</span> <span class="nv">$fullName</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The annotation is defined with one or a list of field names. During hydration,
these fields will be checked in order and, for each field present, the annotated
method will be invoked with its value as a single argument. Since the
<code class="docutils literal"><span class="pre">firstName</span></code> and <code class="docutils literal"><span class="pre">lastName</span></code> fields are mapped, they would then be updated
when the Person was persisted back to MongoDB.</p>
<p>Unlike lifecycle callbacks, the <code class="docutils literal"><span class="pre">&#64;AlsoLoad</span></code> method annotation does not require
the <a class="reference internal" href="annotations-reference.html#haslifecyclecallbacks"><span class="std std-ref">&#64;HasLifecycleCallbacks</span></a> class annotation to be present.</p>
</div>
<div class="section" id="moving-fields">
<h2>Moving Fields<a class="headerlink" href="#moving-fields" title="Permalink to this headline"></a></h2>
<p>Migrating your schema can be a difficult task, but Doctrine provides a few
different methods for dealing with it:</p>
<ul class="simple">
<li><strong>&#64;AlsoLoad</strong> - load values from old fields or transform data through methods</li>
<li><strong>&#64;NotSaved</strong> - load values into fields without saving them again</li>
<li><strong>&#64;PostLoad</strong> - execute code after all fields have been loaded</li>
<li><strong>&#64;PrePersist</strong> - execute code before your document gets saved</li>
</ul>
<p>Imagine you have some address-related fields on a Person document:</p>
<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">Person</span>
<span class="p">{</span>
<span class="sd">/** @Id */</span>
<span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">public</span> <span class="nv">$name</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">public</span> <span class="nv">$street</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">public</span> <span class="nv">$city</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Later on, you may want to migrate this data into an embedded Address document:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/** @EmbeddedDocument */</span>
<span class="k">class</span> <span class="nc">Address</span>
<span class="p">{</span>
<span class="sd">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">public</span> <span class="nv">$street</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">public</span> <span class="nv">$city</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="nv">$street</span><span class="p">,</span> <span class="nv">$city</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">street</span> <span class="o">=</span> <span class="nv">$street</span><span class="p">;</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">city</span> <span class="o">=</span> <span class="nv">$city</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="sd">/** @Document @HasLifecycleCallbacks */</span>
<span class="k">class</span> <span class="nc">Person</span>
<span class="p">{</span>
<span class="sd">/** @Id */</span>
<span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">public</span> <span class="nv">$name</span><span class="p">;</span>
<span class="sd">/** @NotSaved */</span>
<span class="k">public</span> <span class="nv">$street</span><span class="p">;</span>
<span class="sd">/** @NotSaved */</span>
<span class="k">public</span> <span class="nv">$city</span><span class="p">;</span>
<span class="sd">/** @EmbedOne(targetDocument=&quot;Address&quot;) */</span>
<span class="k">public</span> <span class="nv">$address</span><span class="p">;</span>
<span class="sd">/** @PostLoad */</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">postLoad</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">street</span> <span class="o">!==</span> <span class="k">null</span> <span class="o">||</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">city</span> <span class="o">!==</span> <span class="k">null</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">address</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Address</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">street</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">city</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Person's <code class="docutils literal"><span class="pre">street</span></code> and <code class="docutils literal"><span class="pre">city</span></code> fields will be hydrated, but not saved. Once
the Person has loaded, the <code class="docutils literal"><span class="pre">postLoad()</span></code> method will be invoked and construct
a new Address object, which is mapped and will be persisted.</p>
<p>Alternatively, you could defer this migration until the Person is saved:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/** @Document @HasLifecycleCallbacks */</span>
<span class="k">class</span> <span class="nc">Person</span>
<span class="p">{</span>
<span class="c1">// ...</span>
<span class="sd">/** @PrePersist */</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">prePersist</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">street</span> <span class="o">!==</span> <span class="k">null</span> <span class="o">||</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">city</span> <span class="o">!==</span> <span class="k">null</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">address</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Address</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">street</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">city</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The <a class="reference internal" href="annotations-reference.html#haslifecyclecallbacks"><span class="std std-ref">&#64;HasLifecycleCallbacks</span></a> annotation must be present on the class in
which the method is declared for the lifecycle callback to be registered.</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="#">Migrating Schemas</a><ul>
<li><a class="reference internal" href="#renaming-a-field">Renaming a Field</a></li>
<li><a class="reference internal" href="#transforming-data">Transforming Data</a></li>
<li><a class="reference internal" href="#moving-fields">Moving Fields</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/migrating-schemas.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>
@@ -0,0 +1,299 @@
<!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>Priming References &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="priming-references">
<h1>Priming References<a class="headerlink" href="#priming-references" title="Permalink to this headline"></a></h1>
<p>Priming references allows you to consolidate database queries when working with
<a class="reference internal" href="reference-mapping.html#reference-one"><span class="std std-ref">one</span></a> and <a class="reference internal" href="reference-mapping.html#reference-many"><span class="std std-ref">many</span></a> reference mappings.
This is useful for avoiding the
<a class="reference external" href="http://stackoverflow.com/q/97197/162228">n+1 problem</a> in your application.</p>
<div class="section" id="query-builder">
<h2>Query Builder<a class="headerlink" href="#query-builder" title="Permalink to this headline"></a></h2>
<p>Consider the following abbreviated model:</p>
<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="sd">/** @ReferenceMany(targetDocument=&quot;Account&quot;) */</span>
<span class="k">private</span> <span class="nv">$accounts</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>We would like to query for 100 users and then iterate over their referenced
accounts.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$qb</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;User&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">limit</span><span class="p">(</span><span class="mi">100</span><span class="p">);</span>
<span class="nv">$query</span> <span class="o">=</span> <span class="nv">$qb</span><span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">();</span>
<span class="nv">$users</span> <span class="o">=</span> <span class="nv">$query</span><span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$users</span> <span class="k">as</span> <span class="nv">$user</span><span class="p">)</span> <span class="p">{</span>
<span class="cm">/* PersistentCollection::initialize() will be invoked when we begin</span>
<span class="cm"> * iterating through the user&#39;s accounts. Any accounts not already</span>
<span class="cm"> * managed by the unit of work will need to be queried.</span>
<span class="cm"> */</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$user</span><span class="o">-&gt;</span><span class="na">getAccounts</span><span class="p">()</span> <span class="k">as</span> <span class="nv">$account</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// ...</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>In this example, ODM would query the database once for the result set of users
and then, for each user, issue a separate query to load any accounts that are
not already being managed by the unit of work. This could result in as many as
100 additional database queries!</p>
<p>If we expect to iterate through all users and their accounts, we could optimize
this process by loading all of the referenced accounts with one query. The query
builder's <code class="docutils literal"><span class="pre">prime()</span></code> method allows us to do just that.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$qb</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;User&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;accounts&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">prime</span><span class="p">(</span><span class="k">true</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">limit</span><span class="p">(</span><span class="mi">100</span><span class="p">);</span>
<span class="nv">$query</span> <span class="o">=</span> <span class="nv">$qb</span><span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">();</span>
<span class="cm">/* After querying for the users, ODM will collect the IDs of all referenced</span>
<span class="cm"> * accounts and load them with a single additional query.</span>
<span class="cm"> */</span>
<span class="nv">$users</span> <span class="o">=</span> <span class="nv">$query</span><span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$users</span> <span class="k">as</span> <span class="nv">$user</span><span class="p">)</span> <span class="p">{</span>
<span class="cm">/* Accounts have already been loaded, so iterating through accounts will</span>
<span class="cm"> * not query an additional query.</span>
<span class="cm"> */</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$user</span><span class="o">-&gt;</span><span class="na">getAccounts</span><span class="p">()</span> <span class="k">as</span> <span class="nv">$account</span><span class="p">)</span> <span class="p">{</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>In this case, priming will allow us to load all users and referenced accounts in
two database queries. If the accounts had used an
<a class="reference internal" href="inheritance-mapping.html#inheritance-mapping"><span class="std std-ref">inheritance mapping</span></a>, priming might require several
queries (one per discriminated class name).</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Priming is also compatible with <a class="reference internal" href="reference-mapping.html#storing-references"><span class="std std-ref">simple references</span></a>
and discriminated references. When priming discriminated references, ODM
will issue one query per distinct class among the referenced document(s).</p>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Hydration must be enabled in the query builder for priming to work properly.
Disabling hydration will cause the DBRef to be returned for a referenced
document instead of the hydrated document object.</p>
</div>
</div>
<div class="section" id="inverse-references">
<h2>Inverse references<a class="headerlink" href="#inverse-references" title="Permalink to this headline"></a></h2>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">This feature was added in version 1.2.</p>
</div>
<p>When using inverse references (references mapped using <code class="docutils literal"><span class="pre">mappedBy</span></code> or
<code class="docutils literal"><span class="pre">repositoryMethod</span></code>) you can also enable primers on one-to-many references by
specifying them in the mapping:</p>
<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="sd">/** @ReferenceMany(targetDocument=&quot;Account&quot;, prime={&quot;user&quot;}) */</span>
<span class="k">private</span> <span class="nv">$accounts</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>When the collection is initialized, the configured primers are automatically
added to the query.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">When using inverse references with <code class="docutils literal"><span class="pre">repositoryMethod</span></code>, be sure to return
an eager cursor from the repository method if you want to rely on primers
defined in the mapping. If the result is not an eager cursor, an exception
will be thrown and the collection won't be loaded. Also, any primers you
might have added in the <code class="docutils literal"><span class="pre">repositoryMethod</span></code> are overwritten with those
specified in the mapping.</p>
</div>
</div>
<div class="section" id="primer-callback">
<h2>Primer Callback<a class="headerlink" href="#primer-callback" title="Permalink to this headline"></a></h2>
<p>Passing <code class="docutils literal"><span class="pre">true</span></code> to <code class="docutils literal"><span class="pre">prime()</span></code> instructs ODM to load the referenced document(s)
on its own; however, we can also pass a custom callable (e.g. Closure instance)
to <code class="docutils literal"><span class="pre">prime()</span></code>, which allows more control over the priming query.</p>
<p>As an example, we can look at the default callable, which is found in the
<code class="docutils literal"><span class="pre">ReferencePrimer</span></code> class.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">function</span><span class="p">(</span><span class="nx">DocumentManager</span> <span class="nv">$dm</span><span class="p">,</span> <span class="nx">ClassMetadata</span> <span class="nv">$class</span><span class="p">,</span> <span class="k">array</span> <span class="nv">$ids</span><span class="p">,</span> <span class="k">array</span> <span class="nv">$hints</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$qb</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="nv">$class</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="nv">$class</span><span class="o">-&gt;</span><span class="na">identifier</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">in</span><span class="p">(</span><span class="nv">$ids</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span> <span class="o">!</span> <span class="k">empty</span><span class="p">(</span><span class="nv">$hints</span><span class="p">[</span><span class="nx">Query</span><span class="o">::</span><span class="na">HINT_SLAVE_OKAY</span><span class="p">]))</span> <span class="p">{</span>
<span class="nv">$qb</span><span class="o">-&gt;</span><span class="na">slaveOkay</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span> <span class="o">!</span> <span class="k">empty</span><span class="p">(</span><span class="nv">$hints</span><span class="p">[</span><span class="nx">Query</span><span class="o">::</span><span class="na">HINT_READ_PREFERENCE</span><span class="p">]))</span> <span class="p">{</span>
<span class="nv">$qb</span><span class="o">-&gt;</span><span class="na">setReadPreference</span><span class="p">(</span>
<span class="nv">$hints</span><span class="p">[</span><span class="nx">Query</span><span class="o">::</span><span class="na">HINT_READ_PREFERENCE</span><span class="p">],</span>
<span class="nv">$hints</span><span class="p">[</span><span class="nx">Query</span><span class="o">::</span><span class="na">HINT_READ_PREFERENCE_TAGS</span><span class="p">]</span>
<span class="p">);</span>
<span class="p">}</span>
<span class="nv">$qb</span><span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">toArray</span><span class="p">();</span>
<span class="p">};</span>
</pre></div>
</div>
<p>Firstly, the callable is passed the <code class="docutils literal"><span class="pre">DocumentManager</span></code> of the main query. This
is necessary to create the query used for priming, and ensures that the results
will become managed in the same scope. The <code class="docutils literal"><span class="pre">ClassMetadata</span></code> argument provides
mapping information for the referenced class as well as its name, which is used
to create the query builder. An array of identifiers follows, which is used to
query for the documents to be primed. Lastly, the <code class="docutils literal"><span class="pre">UnitOfWork</span></code> hints from the
original query are provided so that the priming query can apply them as well.</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="#">Priming References</a><ul>
<li><a class="reference internal" href="#query-builder">Query Builder</a></li>
<li><a class="reference internal" href="#inverse-references">Inverse references</a></li>
<li><a class="reference internal" href="#primer-callback">Primer Callback</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/priming-references.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>
@@ -0,0 +1,625 @@
<!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>
@@ -0,0 +1,204 @@
<!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>Sharding &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="sharding">
<span id="id1"></span><h1>Sharding<a class="headerlink" href="#sharding" title="Permalink to this headline"></a></h1>
<p>MongoDB allows you to horizontally scale your database. In order to enable this,
Doctrine MongoDB ODM needs to know about your sharding setup. For basic information
about sharding, please refer to the <a class="reference external" href="https://docs.mongodb.com/manual/sharding/">MongoDB docs</a>.</p>
<p>Once you have a <a class="reference external" href="https://docs.mongodb.com/manual/core/sharded-cluster-architectures-production/">sharded cluster</a>,
you can enable sharding for a document. You can do this by defining a shard key in
the 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">/**</span>
<span class="sd"> * @Document</span>
<span class="sd"> * @ShardKey(keys={&quot;username&quot;=&quot;asc&quot;})</span>
<span class="sd"> */</span>
<span class="k">class</span> <span class="nc">User</span>
<span class="p">{</span>
<span class="sd">/** @Id */</span>
<span class="k">public</span> <span class="nv">$id</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;int&quot;) */</span>
<span class="k">public</span> <span class="nv">$accountId</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">public</span> <span class="nv">$username</span><span class="p">;</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;doctrine-mongo-mapping</span> <span class="na">xmlns=</span><span class="s">&quot;http://doctrine-project.org/schemas/orm/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/orm/doctrine-mongo-mapping</span>
<span class="s"> http://doctrine-project.org/schemas/orm/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\User&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;shard-key&gt;</span>
<span class="nt">&lt;key</span> <span class="na">name=</span><span class="s">&quot;username&quot;</span> <span class="na">order=</span><span class="s">&quot;asc&quot;</span><span class="nt">/&gt;</span>
<span class="nt">&lt;/shard-key&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">Documents\User</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">shardKey</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">keys</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">username</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">asc</span>
</pre></div>
</div>
</li>
</ul>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">When a shard key is defined for a document, Doctrine MongoDB ODM will no
longer persist changes to the shard key as these fields become immutable in
a sharded setup.</p>
</div>
<p>Once you've defined a shard key you need to enable sharding for the collection
where the document will be stored. To do this, use the <code class="docutils literal"><span class="pre">odm:schema:shard</span></code>
command.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">For performance reasons, sharding is not enabled during the
<code class="docutils literal"><span class="pre">odm:schema:create</span></code> and <code class="docutils literal"><span class="pre">odm:schema:update</span></code> commmands.</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>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/sharding.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>
@@ -0,0 +1,208 @@
<!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>Slave Okay Queries &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="slave-okay-queries">
<h1>Slave Okay Queries<a class="headerlink" href="#slave-okay-queries" title="Permalink to this headline"></a></h1>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last"><code class="docutils literal"><span class="pre">slaveOkay</span></code> was deprecated in 1.2 - please use <a class="reference external" href="http://php.net/manual/en/mongo.readpreferences.php">Read Preference</a>
instead.</p>
</div>
<div class="section" id="documents">
<h2>Documents<a class="headerlink" href="#documents" title="Permalink to this headline"></a></h2>
<p>You can configure an entire document to send all reads to the slaves by using the <code class="docutils literal"><span class="pre">slaveOkay</span></code> flag:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/** @Document(slaveOkay=true) */</span>
<span class="k">class</span> <span class="nc">User</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="p">}</span>
</pre></div>
</div>
<p>Now all reads involving the <code class="docutils literal"><span class="pre">User</span></code> document will be sent to a slave.</p>
</div>
<div class="section" id="queries">
<h2>Queries<a class="headerlink" href="#queries" title="Permalink to this headline"></a></h2>
<p>If you want to instruct individual queries to read from a slave you can use the <code class="docutils literal"><span class="pre">slaveOkay()</span></code> method
on the query builder.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$qb</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;User&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">slaveOkay</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>
<span class="nv">$query</span> <span class="o">=</span> <span class="nv">$qb</span><span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">();</span>
<span class="nv">$users</span> <span class="o">=</span> <span class="nv">$query</span><span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
</pre></div>
</div>
<p>The data in the query above will be read from a slave. Even if you have a <code class="docutils literal"><span class="pre">&#64;ReferenceOne</span></code> or
<code class="docutils literal"><span class="pre">&#64;ReferenceMany</span></code> resulting from the query above it will be initialized and loaded from a slave.</p>
<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="sd">/** @ReferenceMany(targetDocument=&quot;Account&quot;) */</span>
<span class="k">private</span> <span class="nv">$accounts</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Now when you query and iterate over the accounts, they will be loaded from a slave:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$qb</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;User&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">slaveOkay</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>
<span class="nv">$query</span> <span class="o">=</span> <span class="nv">$qb</span><span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">();</span>
<span class="nv">$users</span> <span class="o">=</span> <span class="nv">$query</span><span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$users</span> <span class="k">as</span> <span class="nv">$user</span><span class="p">)</span> <span class="p">{</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$user</span><span class="o">-&gt;</span><span class="na">getAccounts</span><span class="p">()</span> <span class="k">as</span> <span class="nv">$account</span><span class="p">)</span> <span class="p">{</span>
<span class="k">echo</span> <span class="nv">$account</span><span class="o">-&gt;</span><span class="na">getName</span><span class="p">();</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</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="#">Slave Okay Queries</a><ul>
<li><a class="reference internal" href="#documents">Documents</a></li>
<li><a class="reference internal" href="#queries">Queries</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/slave-okay-queries.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>
@@ -0,0 +1,228 @@
<!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>Storage Strategies &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="storage-strategies">
<span id="id1"></span><h1>Storage Strategies<a class="headerlink" href="#storage-strategies" title="Permalink to this headline"></a></h1>
<p>Doctrine MongoDB ODM implements several different strategies for persisting changes
to mapped fields. These strategies apply to the following mapping types:</p>
<ul class="simple">
<li><span class="xref std std-ref">int</span></li>
<li><span class="xref std std-ref">float</span></li>
<li><a class="reference internal" href="embedded-mapping.html#embed-many"><span class="std std-ref">Embed Many</span></a></li>
<li><a class="reference internal" href="reference-mapping.html#reference-many"><span class="std std-ref">Reference Many</span></a></li>
</ul>
<p>For collections, Doctrine tracks changes via the PersistentCollection class. The
strategies described on this page are implemented by the CollectionPersister
class. The <code class="docutils literal"><span class="pre">increment</span></code> strategy cannot be used for collections.</p>
<div class="section" id="increment">
<h2>increment<a class="headerlink" href="#increment" title="Permalink to this headline"></a></h2>
<p>The <code class="docutils literal"><span class="pre">increment</span></code> strategy does not apply to collections but can be used for
<code class="docutils literal"><span class="pre">int</span></code> and <code class="docutils literal"><span class="pre">float</span></code> fields. When using the <code class="docutils literal"><span class="pre">increment</span></code> strategy, the field
value will be updated using the <a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/update/inc/">$inc</a> operator.</p>
</div>
<div class="section" id="addtoset">
<h2>addToSet<a class="headerlink" href="#addtoset" title="Permalink to this headline"></a></h2>
<p>The <code class="docutils literal"><span class="pre">addToSet</span></code> strategy uses MongoDB's <a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/update/addToSet/">$addToSet</a> operator to insert
elements into the array. This strategy is useful for ensuring that duplicate
values will not be inserted into the collection. Like the <a class="reference internal" href="#pushall">pushAll</a> strategy,
elements are inserted in a separate query after removing deleted elements.</p>
</div>
<div class="section" id="set">
<h2>set<a class="headerlink" href="#set" title="Permalink to this headline"></a></h2>
<p>The <code class="docutils literal"><span class="pre">set</span></code> strategy uses MongoDB's <a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/update/set/">$set</a> operator to update the entire
collection with a single update query.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Doctrine's Collection interface is modeled after PHP's associative arrays,
so they cannot always be represented as a BSON array. If the collection's
keys are not sequential integers starting with zero, the <code class="docutils literal"><span class="pre">set</span></code> strategy
will store the collection as a BSON object instead of an array. Use the
<a class="reference internal" href="#setarray">setArray</a> strategy if you want to ensure that the collection is always
stored as a BSON array.</p>
</div>
</div>
<div class="section" id="setarray">
<h2>setArray<a class="headerlink" href="#setarray" title="Permalink to this headline"></a></h2>
<p>The <code class="docutils literal"><span class="pre">setArray</span></code> strategy uses MongoDB's <a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/update/set/">$set</a> operator, just like the <code class="docutils literal"><span class="pre">set</span></code>
strategy, but will first numerically reindex the collection to ensure that it is
stored as a BSON array.</p>
</div>
<div class="section" id="pushall">
<h2>pushAll<a class="headerlink" href="#pushall" title="Permalink to this headline"></a></h2>
<p>The <code class="docutils literal"><span class="pre">pushAll</span></code> strategy uses MongoDB's <a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/update/pushAll/">$pushAll</a> operator to insert
elements into the array. MongoDB does not allow elements to be added and removed
from an array in a single operation, so this strategy relies on multiple update
queries to remove and insert elements (in that order).</p>
</div>
<div class="section" id="atomicset">
<span id="atomic-set"></span><h2>atomicSet<a class="headerlink" href="#atomicset" title="Permalink to this headline"></a></h2>
<p>The <code class="docutils literal"><span class="pre">atomicSet</span></code> strategy uses MongoDB's <a class="reference external" href="https://docs.mongodb.com/manual/reference/operator/update/set/">$set</a> operator to update the entire
collection with a single update query. Unlike with <code class="docutils literal"><span class="pre">set</span></code> strategy there will
be only one query for updating both parent document and collection itself. This
strategy can be especially useful when dealing with high concurrency and
<a class="reference internal" href="annotations-reference.html#annotations-reference-version"><span class="std std-ref">versioned documents</span></a>.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">The <code class="docutils literal"><span class="pre">atomicSet</span></code> and <code class="docutils literal"><span class="pre">atomicSetArray</span></code> strategies may only be used for
collections mapped directly in a top-level document.</p>
</div>
</div>
<div class="section" id="atomicsetarray">
<span id="atomic-set-array"></span><h2>atomicSetArray<a class="headerlink" href="#atomicsetarray" title="Permalink to this headline"></a></h2>
<p>The <code class="docutils literal"><span class="pre">atomicSetArray</span></code> strategy works exactly like <code class="docutils literal"><span class="pre">atomicSet</span></code> strategy, but
will first numerically reindex the collection to ensure that it is stored as a
BSON array.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">The <code class="docutils literal"><span class="pre">atomicSet</span></code> and <code class="docutils literal"><span class="pre">atomicSetArray</span></code> strategies may only be used for
collections mapped directly in a top-level document.</p>
</div>
</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="#">Storage Strategies</a><ul>
<li><a class="reference internal" href="#increment">increment</a></li>
<li><a class="reference internal" href="#addtoset">addToSet</a></li>
<li><a class="reference internal" href="#set">set</a></li>
<li><a class="reference internal" href="#setarray">setArray</a></li>
<li><a class="reference internal" href="#pushall">pushAll</a></li>
<li><a class="reference internal" href="#atomicset">atomicSet</a></li>
<li><a class="reference internal" href="#atomicsetarray">atomicSetArray</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/storage-strategies.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>
@@ -0,0 +1,311 @@
<!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>Storing Files with MongoGridFS &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="storing-files-with-mongogridfs">
<h1>Storing Files with MongoGridFS<a class="headerlink" href="#storing-files-with-mongogridfs" title="Permalink to this headline"></a></h1>
<p>The PHP Mongo extension provides a nice and convenient way to store
files in chunks of data with the
<a class="reference external" href="http://us.php.net/manual/en/class.mongogridfs.php">MongoGridFS</a>.</p>
<p>It uses two database collections, one to store the metadata for the
file, and another to store the contents of the file. The contents
are stored in chunks to avoid going over the maximum allowed size
of a MongoDB document.</p>
<p>You can easily setup a Document that is stored using the
MongoGridFS:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
<span class="sd">/** @Document */</span>
<span class="k">class</span> <span class="nc">Image</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">/** @Field */</span>
<span class="k">private</span> <span class="nv">$name</span><span class="p">;</span>
<span class="sd">/** @File */</span>
<span class="k">private</span> <span class="nv">$file</span><span class="p">;</span>
<span class="sd">/** @Field */</span>
<span class="k">private</span> <span class="nv">$uploadDate</span><span class="p">;</span>
<span class="sd">/** @Field */</span>
<span class="k">private</span> <span class="nv">$length</span><span class="p">;</span>
<span class="sd">/** @Field */</span>
<span class="k">private</span> <span class="nv">$chunkSize</span><span class="p">;</span>
<span class="sd">/** @Field */</span>
<span class="k">private</span> <span class="nv">$md5</span><span class="p">;</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">getId</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">id</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">setName</span><span class="p">(</span><span class="nv">$name</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">name</span> <span class="o">=</span> <span class="nv">$name</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">getName</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">getFile</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">file</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">setFile</span><span class="p">(</span><span class="nv">$file</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">file</span> <span class="o">=</span> <span class="nv">$file</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Notice how we annotated the $file property with &#64;File. This is what
tells the Document that it is to be stored using the MongoGridFS
and the MongoGridFSFile instance is placed in the $file property
for you to access the actual file itself.</p>
<p>The $uploadDate, $chunkSize and $md5 properties are automatically filled in
for each file stored in GridFS (whether you like that or not).
Feel free to create getters in your document to actually make use of them,
but keep in mind that their values will be initially unset for new objects
until the next time the document is hydrated (fetched from the database).</p>
<p>First you need to create a new Image:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$image</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Image</span><span class="p">();</span>
<span class="nv">$image</span><span class="o">-&gt;</span><span class="na">setName</span><span class="p">(</span><span class="s1">&#39;Test image&#39;</span><span class="p">);</span>
<span class="nv">$image</span><span class="o">-&gt;</span><span class="na">setFile</span><span class="p">(</span><span class="s1">&#39;/path/to/image.png&#39;</span><span class="p">);</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">persist</span><span class="p">(</span><span class="nv">$image</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>Now you can later query for the Image and render it:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$image</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;Documents\Image&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">equals</span><span class="p">(</span><span class="s1">&#39;Test image&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">getSingleResult</span><span class="p">();</span>
<span class="nb">header</span><span class="p">(</span><span class="s1">&#39;Content-type: image/png;&#39;</span><span class="p">);</span>
<span class="k">echo</span> <span class="nv">$image</span><span class="o">-&gt;</span><span class="na">getFile</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">getBytes</span><span class="p">();</span>
</pre></div>
</div>
<p>You can of course make references to this Image document from
another document. Imagine you had a Profile document and you wanted
every Profile to have a profile image:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">namespace</span> <span class="nx">Documents</span><span class="p">;</span>
<span class="sd">/** @Document */</span>
<span class="k">class</span> <span class="nc">Profile</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">/** @Field */</span>
<span class="k">private</span> <span class="nv">$name</span><span class="p">;</span>
<span class="sd">/** @ReferenceOne(targetDocument=&quot;Documents\Image&quot;) */</span>
<span class="k">private</span> <span class="nv">$image</span><span class="p">;</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">getId</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">id</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">getName</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">name</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">setName</span><span class="p">(</span><span class="nv">$name</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">name</span> <span class="o">=</span> <span class="nv">$name</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">getImage</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">image</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">setImage</span><span class="p">(</span><span class="nx">Image</span> <span class="nv">$image</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">image</span> <span class="o">=</span> <span class="nv">$image</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Now you can create a new Profile and give it an Image:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$image</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Image</span><span class="p">();</span>
<span class="nv">$image</span><span class="o">-&gt;</span><span class="na">setName</span><span class="p">(</span><span class="s1">&#39;Test image&#39;</span><span class="p">);</span>
<span class="nv">$image</span><span class="o">-&gt;</span><span class="na">setFile</span><span class="p">(</span><span class="s1">&#39;/path/to/image.png&#39;</span><span class="p">);</span>
<span class="nv">$profile</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Profile</span><span class="p">();</span>
<span class="nv">$profile</span><span class="o">-&gt;</span><span class="na">setName</span><span class="p">(</span><span class="s1">&#39;Jonathan H. Wage&#39;</span><span class="p">);</span>
<span class="nv">$profile</span><span class="o">-&gt;</span><span class="na">setImage</span><span class="p">(</span><span class="nv">$image</span><span class="p">);</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">persist</span><span class="p">(</span><span class="nv">$profile</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>If you want to query for the Profile and load the Image reference
in a query you can use:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$profile</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;Profile&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">equals</span><span class="p">(</span><span class="s1">&#39;Jonathan H. Wage&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">getSingleResult</span><span class="p">();</span>
<span class="nv">$image</span> <span class="o">=</span> <span class="nv">$profile</span><span class="o">-&gt;</span><span class="na">getImage</span><span class="p">();</span>
<span class="nb">header</span><span class="p">(</span><span class="s1">&#39;Content-type: image/png;&#39;</span><span class="p">);</span>
<span class="k">echo</span> <span class="nv">$image</span><span class="o">-&gt;</span><span class="na">getFile</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">getBytes</span><span class="p">();</span>
</pre></div>
</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>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/storing-files-with-mongogridfs.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>
@@ -0,0 +1,458 @@
<!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>Transactions and Concurrency &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="transactions-and-concurrency">
<h1>Transactions and Concurrency<a class="headerlink" href="#transactions-and-concurrency" title="Permalink to this headline"></a></h1>
<div class="section" id="transactions">
<h2>Transactions<a class="headerlink" href="#transactions" title="Permalink to this headline"></a></h2>
<p>As per the <a class="reference external" href="https://docs.mongodb.com/manual/core/write-operations-atomicity/#atomicity-and-transactions">documentation</a>, MongoDB
write operations are &quot;atomic on the level of a single document&quot;.</p>
<p>Even when updating multiple documents within a single write operation,
though the modification of each document is atomic,
the operation as a whole is not and other operations may interleave.</p>
<p>As stated in the <a class="reference external" href="https://docs.mongodb.com/manual/faq/fundamentals/#does-mongodb-support-transactions">FAQ</a>,
&quot;MongoDB does not support multi-document transactions&quot; and neither does Doctrine MongoDB ODM.</p>
<div class="section" id="limitation">
<h3>Limitation<a class="headerlink" href="#limitation" title="Permalink to this headline"></a></h3>
<p>At the moment, Doctrine MongoDB ODM does not provide any native strategy to emulate multi-document transactions.</p>
</div>
<div class="section" id="workaround">
<h3>Workaround<a class="headerlink" href="#workaround" title="Permalink to this headline"></a></h3>
<p>To work around this limitation, one can utilize <a class="reference external" href="https://docs.mongodb.com/manual/tutorial/perform-two-phase-commits/">two phase commits</a>.</p>
</div>
</div>
<div class="section" id="concurrency">
<h2>Concurrency<a class="headerlink" href="#concurrency" title="Permalink to this headline"></a></h2>
<p>Doctrine MongoDB ODM offers native support for pessimistic and optimistic locking strategies.
This allows for very fine-grained control over what kind of locking is required for documents in your application.</p>
<div class="section" id="optimistic-locking">
<span id="transactions-and-concurrency-optimistic-locking"></span><h3>Optimistic Locking<a class="headerlink" href="#optimistic-locking" title="Permalink to this headline"></a></h3>
<div class="section" id="approach">
<h4>Approach<a class="headerlink" href="#approach" title="Permalink to this headline"></a></h4>
<p>Doctrine has integrated support for automatic optimistic locking
via a <code class="docutils literal"><span class="pre">version</span></code> field. Any document that should be
protected against concurrent modifications during long-running
business transactions gets a <code class="docutils literal"><span class="pre">version</span></code> field that is either a simple
number (mapping type: <code class="docutils literal"><span class="pre">int</span></code>) or a date (mapping type: <code class="docutils literal"><span class="pre">date</span></code>).
When changes to the document are persisted,
the expected version and version increment are incorporated into the update criteria and modifiers, respectively.
If this results in no document being modified by the update (i.e. expected version did not match),
a <code class="docutils literal"><span class="pre">LockException</span></code> is thrown, which indicates that the document was already modified by another query.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<div class="last line-block">
<div class="line">Versioning can only be used on <em>root</em> (top-level) documents.</div>
</div>
</div>
</div>
<div class="section" id="document-configuration">
<h4>Document Configuration<a class="headerlink" href="#document-configuration" title="Permalink to this headline"></a></h4>
<p>The following example designates a version field using the <code class="docutils literal"><span class="pre">int</span></code> type:</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">/** @Version @Field(type=&quot;int&quot;) */</span>
<span class="k">private</span> <span class="nv">$version</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;version&quot;</span> <span class="na">version=</span><span class="s">&quot;true&quot;</span> <span class="na">type=</span><span class="s">&quot;int&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">version</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">int</span>
<span class="l l-Scalar l-Scalar-Plain">version</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
</pre></div>
</div>
</li>
</ul>
</div>
<p>Alternatively, the <code class="docutils literal"><span class="pre">date</span></code> type may be used:</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">/** @Version @Field(type=&quot;date&quot;) */</span>
<span class="k">private</span> <span class="nv">$version</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;version&quot;</span> <span class="na">version=</span><span class="s">&quot;true&quot;</span> <span class="na">type=</span><span class="s">&quot;date&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">version</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">date</span>
<span class="l l-Scalar l-Scalar-Plain">version</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
</pre></div>
</div>
</li>
</ul>
</div>
<div class="section" id="choosing-the-field-type">
<h5>Choosing the Field Type<a class="headerlink" href="#choosing-the-field-type" title="Permalink to this headline"></a></h5>
<p>When using the <code class="docutils literal"><span class="pre">date</span></code> type in a high-concurrency environment, it is still possible to create multiple documents
with the same version and cause a conflict. This can be avoided by using the <code class="docutils literal"><span class="pre">int</span></code> type.</p>
</div>
<div class="section" id="usage">
<h5>Usage<a class="headerlink" href="#usage" title="Permalink to this headline"></a></h5>
<p>When a version conflict is encountered during
<code class="docutils literal"><span class="pre">DocumentManager#flush()</span></code>, a <code class="docutils literal"><span class="pre">LockException</span></code> is thrown.
This exception can be caught and handled. Potential responses to a
<code class="docutils literal"><span class="pre">LockException</span></code> are to present the conflict to the user or
to refresh or reload objects and then retry the update.</p>
<p>With PHP promoting a share-nothing architecture,
the worst case scenario for a delay between rendering an update form (with existing document data)
and modifying the document after a form submission may be your application's session timeout.
If the document is changed within that time frame by some other request,
it may be preferable to encounter a <code class="docutils literal"><span class="pre">LockException</span></code> when retrieving the document instead of executing the update.</p>
<p>You can specify the expected version of a document during a query with <code class="docutils literal"><span class="pre">DocumentManager#find()</span></code>:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\LockMode</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\LockException</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\DocumentManager</span><span class="p">;</span>
<span class="nv">$theDocumentId</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="nv">$expectedVersion</span> <span class="o">=</span> <span class="mi">184</span><span class="p">;</span>
<span class="cm">/* @var $dm DocumentManager */</span>
<span class="k">try</span> <span class="p">{</span>
<span class="nv">$document</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="s1">&#39;User&#39;</span><span class="p">,</span> <span class="nv">$theDocumentId</span><span class="p">,</span> <span class="nx">LockMode</span><span class="o">::</span><span class="na">OPTIMISTIC</span><span class="p">,</span> <span class="nv">$expectedVersion</span><span class="p">);</span>
<span class="c1">// do the work</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">flush</span><span class="p">();</span>
<span class="p">}</span> <span class="k">catch</span><span class="p">(</span><span class="nx">LockException</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>
<span class="k">echo</span> <span class="s2">&quot;Sorry, but someone else has already changed this document. Please apply the changes again!&quot;</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Alternatively, an expected version may be specified for an existing document with <code class="docutils literal"><span class="pre">DocumentManager#lock()</span></code>:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\LockMode</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\LockException</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\DocumentManager</span><span class="p">;</span>
<span class="nv">$theDocumentId</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
<span class="nv">$expectedVersion</span> <span class="o">=</span> <span class="mi">184</span><span class="p">;</span>
<span class="cm">/* @var $dm DocumentManager */</span>
<span class="nv">$document</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="s1">&#39;User&#39;</span><span class="p">,</span> <span class="nv">$theDocumentId</span><span class="p">);</span>
<span class="k">try</span> <span class="p">{</span>
<span class="c1">// assert version</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">lock</span><span class="p">(</span><span class="nv">$document</span><span class="p">,</span> <span class="nx">LockMode</span><span class="o">::</span><span class="na">OPTIMISTIC</span><span class="p">,</span> <span class="nv">$expectedVersion</span><span class="p">);</span>
<span class="p">}</span> <span class="k">catch</span><span class="p">(</span><span class="nx">LockException</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>
<span class="k">echo</span> <span class="s2">&quot;Sorry, but someone else has already changed this document. Please apply the changes again!&quot;</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
</div>
</div>
</div>
<div class="section" id="important-implementation-notes">
<h4>Important Implementation Notes<a class="headerlink" href="#important-implementation-notes" title="Permalink to this headline"></a></h4>
<p>You can easily get the optimistic locking workflow wrong if you
compare the wrong versions.</p>
<div class="section" id="workflow">
<h5>Workflow<a class="headerlink" href="#workflow" title="Permalink to this headline"></a></h5>
<p>Say you have Alice and Bob editing a
hypothetical blog post:</p>
<ul class="simple">
<li>Alice reads the headline of the blog post being &quot;Foo&quot;, at
optimistic lock version 1 (GET Request)</li>
<li>Bob reads the headline of the blog post being &quot;Foo&quot;, at
optimistic lock version 1 (GET Request)</li>
<li>Bob updates the headline to &quot;Bar&quot;, upgrading the optimistic lock
version to 2 (POST Request of a Form)</li>
<li>Alice updates the headline to &quot;Baz&quot;, ... (POST Request of a
Form)</li>
</ul>
<p>At the last stage of this scenario the blog post has to be read
again from the database before Alice's headline can be applied. At
this point you will want to check if the blog post is still at
version 1 (which it is not in this scenario).</p>
<p>In order to correctly utilize optimistic locking, you <em>must</em> add the version as hidden form field or,
for more security, session attribute.
Otherwise, you cannot verify that the version at the time of update is the same as what was originally read
from the database when Alice performed her original GET request for the blog post.
Without correlating the version across form submissions, the application could lose updates.</p>
</div>
<div class="section" id="example-code">
<h5>Example Code<a class="headerlink" href="#example-code" title="Permalink to this headline"></a></h5>
<p>The form (GET Request):</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\DocumentManager</span><span class="p">;</span>
<span class="cm">/* @var $dm DocumentManager */</span>
<span class="nv">$post</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="s1">&#39;BlogPost&#39;</span><span class="p">,</span> <span class="mi">123456</span><span class="p">);</span>
<span class="k">echo</span> <span class="s1">&#39;&lt;input type=&quot;hidden&quot; name=&quot;id&quot; value=&quot;&#39;</span> <span class="o">.</span> <span class="nv">$post</span><span class="o">-&gt;</span><span class="na">getId</span><span class="p">()</span> <span class="o">.</span> <span class="s1">&#39;&quot; /&gt;&#39;</span><span class="p">;</span>
<span class="k">echo</span> <span class="s1">&#39;&lt;input type=&quot;hidden&quot; name=&quot;version&quot; value=&quot;&#39;</span> <span class="o">.</span> <span class="nv">$post</span><span class="o">-&gt;</span><span class="na">getCurrentVersion</span><span class="p">()</span> <span class="o">.</span> <span class="s1">&#39;&quot; /&gt;&#39;</span><span class="p">;</span>
</pre></div>
</div>
<p>And the change headline action (POST Request):</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\DocumentManager</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Doctrine\ODM\MongoDB\LockMode</span><span class="p">;</span>
<span class="cm">/* @var $dm DocumentManager */</span>
<span class="nv">$postId</span> <span class="o">=</span> <span class="p">(</span><span class="nx">int</span><span class="p">)</span><span class="nv">$_POST</span><span class="p">[</span><span class="s1">&#39;id&#39;</span><span class="p">];</span>
<span class="nv">$postVersion</span> <span class="o">=</span> <span class="p">(</span><span class="nx">int</span><span class="p">)</span><span class="nv">$_POST</span><span class="p">[</span><span class="s1">&#39;version&#39;</span><span class="p">];</span>
<span class="nv">$post</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="s1">&#39;BlogPost&#39;</span><span class="p">,</span> <span class="nv">$postId</span><span class="p">,</span> <span class="nx">LockMode</span><span class="o">::</span><span class="na">OPTIMISTIC</span><span class="p">,</span> <span class="nv">$postVersion</span><span class="p">);</span>
</pre></div>
</div>
</div>
</div>
</div>
<div class="section" id="pessimistic-locking">
<span id="transactions-and-concurrency-pessimistic-locking"></span><h3>Pessimistic Locking<a class="headerlink" href="#pessimistic-locking" title="Permalink to this headline"></a></h3>
<p>Doctrine MongoDB ODM also supports pessimistic locking via a configurable <code class="docutils literal"><span class="pre">lock</span></code> field.
This functionality is implemented entirely by Doctrine; MongoDB has no native support for pessimistic locking.</p>
<div class="section" id="id1">
<h4>Document Configuration<a class="headerlink" href="#id1" title="Permalink to this headline"></a></h4>
<p>Pessimistic locking requires a document to designate a lock field using the <code class="docutils literal"><span class="pre">int</span></code> type:</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">/** @Lock @Field(type=&quot;int&quot;) */</span>
<span class="k">private</span> <span class="nv">$lock</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;lock&quot;</span> <span class="na">lock=</span><span class="s">&quot;true&quot;</span> <span class="na">type=</span><span class="s">&quot;int&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">lock</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">int</span>
<span class="l l-Scalar l-Scalar-Plain">lock</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
</pre></div>
</div>
</li>
</ul>
</div>
</div>
<div class="section" id="lock-modes">
<h4>Lock Modes<a class="headerlink" href="#lock-modes" title="Permalink to this headline"></a></h4>
<p>Doctrine MongoDB ODM currently supports two pessimistic lock modes:</p>
<ul class="simple">
<li>Pessimistic Write
(<code class="docutils literal"><span class="pre">\Doctrine\ODM\MongoDB\LockMode::PESSIMISTIC_WRITE</span></code>): locks the
underlying document for concurrent read and write operations.</li>
<li>Pessimistic Read (<code class="docutils literal"><span class="pre">\Doctrine\ODM\MongoDB\LockMode::PESSIMISTIC_READ</span></code>):
locks other concurrent requests that attempt to update or lock documents
in write mode.</li>
</ul>
</div>
<div class="section" id="id2">
<h4>Usage<a class="headerlink" href="#id2" title="Permalink to this headline"></a></h4>
<p>You can use pessimistic locks in two different scenarios:</p>
<ol class="arabic simple">
<li>Using
<code class="docutils literal"><span class="pre">DocumentManager#find($className,</span> <span class="pre">$id,</span> <span class="pre">\Doctrine\ODM\MongoDB\LockMode::PESSIMISTIC_WRITE)</span></code>
or
<code class="docutils literal"><span class="pre">DocumentManager#find($className,</span> <span class="pre">$id,</span> <span class="pre">\Doctrine\ODM\MongoDB\LockMode::PESSIMISTIC_READ)</span></code></li>
<li>Using
<code class="docutils literal"><span class="pre">DocumentManager#lock($document,</span> <span class="pre">\Doctrine\ODM\MongoDB\LockMode::PESSIMISTIC_WRITE)</span></code>
or
<code class="docutils literal"><span class="pre">DocumentManager#lock($document,</span> <span class="pre">\Doctrine\ODM\MongoDB\LockMode::PESSIMISTIC_READ)</span></code></li>
</ol>
<div class="admonition warning">
<p class="first admonition-title">Warning</p>
<div class="last line-block">
<div class="line">A few things could go wrong:</div>
<div class="line"><br /></div>
<div class="line">If a request fails to complete (e.g. unhandled exception), you may end up with stale locks.
Said locks would need to be manually released or you would need to devise a strategy to automatically do so.
One way to mitigate stale locks after an application error would be to gracefully catch the exception
and ensure that relevant documents are unlocked before the request ends.</div>
<div class="line"><br /></div>
<div class="line"><a class="reference external" href="https://en.wikipedia.org/wiki/Deadlock">Deadlock</a> situations are also possible.
Suppose process P1 needs resource R1 and has locked resource R2
and that another process P2 has locked resource R1 but also needs resource R2.
If both processes continue waiting for the respective resources, the application will be stuck.
When loading a document, Doctrine can immediately throw an exception if it is already locked.
A deadlock could be created by endlessly retrying attempts to acquire the lock.
One can avoid a possible deadlock by designating a maximum number of retry attempts
and automatically releasing any active locks with the request ends,
thereby allowing a process to end gracefully while another completes its task.</div>
</div>
</div>
</div>
</div>
</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="#">Transactions and Concurrency</a><ul>
<li><a class="reference internal" href="#transactions">Transactions</a><ul>
<li><a class="reference internal" href="#limitation">Limitation</a></li>
<li><a class="reference internal" href="#workaround">Workaround</a></li>
</ul>
</li>
<li><a class="reference internal" href="#concurrency">Concurrency</a><ul>
<li><a class="reference internal" href="#optimistic-locking">Optimistic Locking</a><ul>
<li><a class="reference internal" href="#approach">Approach</a></li>
<li><a class="reference internal" href="#document-configuration">Document Configuration</a><ul>
<li><a class="reference internal" href="#choosing-the-field-type">Choosing the Field Type</a></li>
<li><a class="reference internal" href="#usage">Usage</a></li>
</ul>
</li>
<li><a class="reference internal" href="#important-implementation-notes">Important Implementation Notes</a><ul>
<li><a class="reference internal" href="#workflow">Workflow</a></li>
<li><a class="reference internal" href="#example-code">Example Code</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#pessimistic-locking">Pessimistic Locking</a><ul>
<li><a class="reference internal" href="#id1">Document Configuration</a></li>
<li><a class="reference internal" href="#lock-modes">Lock Modes</a></li>
<li><a class="reference internal" href="#id2">Usage</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/transactions-and-concurrency.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>
@@ -0,0 +1,389 @@
<!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>Trees &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="trees">
<h1>Trees<a class="headerlink" href="#trees" title="Permalink to this headline"></a></h1>
<p>MongoDB lends itself quite well to storing hierarchical data. This
chapter will demonstrate some examples!</p>
<div class="section" id="full-tree-in-single-document">
<h2>Full Tree in Single Document<a class="headerlink" href="#full-tree-in-single-document" title="Permalink to this headline"></a></h2>
<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">BlogPost</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">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">private</span> <span class="nv">$title</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">private</span> <span class="nv">$body</span><span class="p">;</span>
<span class="sd">/** @EmbedMany(targetDocument=&quot;Comment&quot;) */</span>
<span class="k">private</span> <span class="nv">$comments</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">/** @EmbeddedDocument */</span>
<span class="k">class</span> <span class="nc">Comment</span>
<span class="p">{</span>
<span class="sd">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">private</span> <span class="nv">$by</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">private</span> <span class="nv">$text</span><span class="p">;</span>
<span class="sd">/** @EmbedMany(targetDocument=&quot;Comment&quot;) */</span>
<span class="k">private</span> <span class="nv">$replies</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>
<p>Retrieve a blog post and only select the first 10 comments:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$post</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;BlogPost&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">selectSlice</span><span class="p">(</span><span class="s1">&#39;replies&#39;</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">getSingleResult</span><span class="p">();</span>
<span class="nv">$replies</span> <span class="o">=</span> <span class="nv">$post</span><span class="o">-&gt;</span><span class="na">getReplies</span><span class="p">();</span>
</pre></div>
</div>
<p>You can read more about this pattern on the MongoDB documentation page &quot;Trees in MongoDB&quot; in the
<a class="reference external" href="http://www.mongodb.org/display/DOCS/Trees+in+MongoDB#TreesinMongoDB-FullTreeinSingleDocument">Full Tree in Single Document</a> section.</p>
</div>
<div class="section" id="parent-reference">
<h2>Parent Reference<a class="headerlink" href="#parent-reference" title="Permalink to this headline"></a></h2>
<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">Category</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">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">private</span> <span class="nv">$name</span><span class="p">;</span>
<span class="sd">/**</span>
<span class="sd"> * @ReferenceOne(targetDocument=&quot;Category&quot;)</span>
<span class="sd"> * @Index</span>
<span class="sd"> */</span>
<span class="k">private</span> <span class="nv">$parent</span><span class="p">;</span>
<span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Query for children by a specific parent id:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$children</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;Category&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;parent.id&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">equals</span><span class="p">(</span><span class="s1">&#39;theid&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
</pre></div>
</div>
<p>You can read more about this pattern on the MongoDB documentation page &quot;Trees in MongoDB&quot; in the
<a class="reference external" href="https://docs.mongodb.com/manual/tutorial/model-tree-structures/#model-tree-structures-with-parent-references">Parent Links</a> section.</p>
</div>
<div class="section" id="child-reference">
<h2>Child Reference<a class="headerlink" href="#child-reference" title="Permalink to this headline"></a></h2>
<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">Category</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">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">private</span> <span class="nv">$name</span><span class="p">;</span>
<span class="sd">/**</span>
<span class="sd"> * @ReferenceMany(targetDocument=&quot;Category&quot;)</span>
<span class="sd"> * @Index</span>
<span class="sd"> */</span>
<span class="k">private</span> <span class="nv">$children</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>
<p>Query for immediate children of a category:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$category</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;Category&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">equals</span><span class="p">(</span><span class="s1">&#39;theid&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">getSingleResult</span><span class="p">();</span>
<span class="nv">$children</span> <span class="o">=</span> <span class="nv">$category</span><span class="o">-&gt;</span><span class="na">getChildren</span><span class="p">();</span>
</pre></div>
</div>
<p>Query for immediate parent of a category:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$parent</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;Category&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;children.id&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">equals</span><span class="p">(</span><span class="s1">&#39;theid&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">getSingleResult</span><span class="p">();</span>
</pre></div>
</div>
<p>You can read more about this pattern on the MongoDB documentation page &quot;Trees in MongoDB&quot; in the
<a class="reference external" href="https://docs.mongodb.com/manual/tutorial/model-tree-structures/#model-tree-structures-with-child-references">Child Links</a> section.</p>
</div>
<div class="section" id="array-of-ancestors">
<h2>Array of Ancestors<a class="headerlink" href="#array-of-ancestors" title="Permalink to this headline"></a></h2>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="sd">/** @MappedSuperclass */</span>
<span class="k">class</span> <span class="nc">BaseCategory</span>
<span class="p">{</span>
<span class="sd">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">private</span> <span class="nv">$name</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">Category</span> <span class="k">extends</span> <span class="nx">BaseCategory</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">/**</span>
<span class="sd"> * @ReferenceMany(targetDocument=&quot;Category&quot;)</span>
<span class="sd"> * @Index</span>
<span class="sd"> */</span>
<span class="k">private</span> <span class="nv">$ancestors</span> <span class="o">=</span> <span class="k">array</span><span class="p">();</span>
<span class="sd">/**</span>
<span class="sd"> * @ReferenceOne(targetDocument=&quot;Category&quot;)</span>
<span class="sd"> * @Index</span>
<span class="sd"> */</span>
<span class="k">private</span> <span class="nv">$parent</span><span class="p">;</span>
<span class="c1">// ...</span>
<span class="p">}</span>
<span class="sd">/** @EmbeddedDocument */</span>
<span class="k">class</span> <span class="nc">SubCategory</span> <span class="k">extends</span> <span class="nx">BaseCategory</span>
<span class="p">{</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Query for all descendants of a category:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$categories</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;Category&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;ancestors.id&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">equals</span><span class="p">(</span><span class="s1">&#39;theid&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
</pre></div>
</div>
<p>Query for all ancestors of a category:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$category</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQuery</span><span class="p">(</span><span class="s1">&#39;Category&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;id&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">equals</span><span class="p">(</span><span class="s1">&#39;theid&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">getSingleResult</span><span class="p">();</span>
<span class="nv">$ancestors</span> <span class="o">=</span> <span class="nv">$category</span><span class="o">-&gt;</span><span class="na">getAncestors</span><span class="p">();</span>
</pre></div>
</div>
<p>You can read more about this pattern on the MongoDB documentation page &quot;Trees in MongoDB&quot; in the
<a class="reference external" href="https://docs.mongodb.com/manual/tutorial/model-tree-structures/#model-tree-structures-with-an-array-of-ancestors">Array of Ancestors</a> section.</p>
</div>
<div class="section" id="materialized-paths">
<h2>Materialized Paths<a class="headerlink" href="#materialized-paths" title="Permalink to this headline"></a></h2>
<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">Category</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">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">private</span> <span class="nv">$name</span><span class="p">;</span>
<span class="sd">/** @Field(type=&quot;string&quot;) */</span>
<span class="k">private</span> <span class="nv">$path</span><span class="p">;</span>
<span class="c1">// ...</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Query for the entire tree:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$categories</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQuery</span><span class="p">(</span><span class="s1">&#39;Category&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">sort</span><span class="p">(</span><span class="s1">&#39;path&#39;</span><span class="p">,</span> <span class="s1">&#39;asc&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
</pre></div>
</div>
<p>Query for the node 'b' and all its descendants:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$categories</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQuery</span><span class="p">(</span><span class="s1">&#39;Category&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;path&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">equals</span><span class="p">(</span><span class="s1">&#39;/^a,b,/&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">()</span>
<span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
</pre></div>
</div>
<p>You can read more about this pattern on the MongoDB documentation page &quot;Trees in MongoDB&quot; in the
<a class="reference external" href="https://docs.mongodb.com/manual/tutorial/model-tree-structures/#model-tree-structures-with-materialized-paths">Materialized Paths (Full Path in Each Node)</a> section.</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="#">Trees</a><ul>
<li><a class="reference internal" href="#full-tree-in-single-document">Full Tree in Single Document</a></li>
<li><a class="reference internal" href="#parent-reference">Parent Reference</a></li>
<li><a class="reference internal" href="#child-reference">Child Reference</a></li>
<li><a class="reference internal" href="#array-of-ancestors">Array of Ancestors</a></li>
<li><a class="reference internal" href="#materialized-paths">Materialized Paths</a></li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/trees.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>
@@ -0,0 +1,165 @@
<!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>Upserting Documents &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="upserting-documents">
<h1>Upserting Documents<a class="headerlink" href="#upserting-documents" title="Permalink to this headline"></a></h1>
<p>Upserting documents in the MongoDB ODM is easy. All you really have to do
is specify an ID ahead of time and Doctrine will perform an <code class="docutils literal"><span class="pre">update</span></code> operation
with the <code class="docutils literal"><span class="pre">upsert</span></code> flag internally instead of a <code class="docutils literal"><span class="pre">batchInsert</span></code>.</p>
<p>Example:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$article</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Article</span><span class="p">();</span>
<span class="nv">$article</span><span class="o">-&gt;</span><span class="na">setId</span><span class="p">(</span><span class="nv">$articleId</span><span class="p">);</span>
<span class="nv">$article</span><span class="o">-&gt;</span><span class="na">incrementNumViews</span><span class="p">();</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">persist</span><span class="p">(</span><span class="nv">$article</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>The above would result in an operation like the following:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$articleCollection</span><span class="o">-&gt;</span><span class="na">update</span><span class="p">(</span>
<span class="k">array</span><span class="p">(</span><span class="s1">&#39;_id&#39;</span> <span class="o">=&gt;</span> <span class="k">new</span> <span class="nx">MongoId</span><span class="p">(</span><span class="nv">$articleId</span><span class="p">)),</span>
<span class="k">array</span><span class="p">(</span><span class="s1">&#39;$inc&#39;</span> <span class="o">=&gt;</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;numViews&#39;</span> <span class="o">=&gt;</span> <span class="mi">1</span><span class="p">)),</span>
<span class="k">array</span><span class="p">(</span><span class="s1">&#39;upsert&#39;</span> <span class="o">=&gt;</span> <span class="k">true</span><span class="p">,</span> <span class="s1">&#39;safe&#39;</span> <span class="o">=&gt;</span> <span class="k">true</span><span class="p">)</span>
<span class="p">);</span>
</pre></div>
</div>
<p>The extra benefit is the fact that you don't have to fetch the <code class="docutils literal"><span class="pre">$article</span></code> in order
to append some new data to the document or change something. All you need is the
identifier.</p>
</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>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/upserting-documents.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>
@@ -0,0 +1,653 @@
<!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>Working with Objects &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="working-with-objects">
<h1>Working with Objects<a class="headerlink" href="#working-with-objects" title="Permalink to this headline"></a></h1>
<div class="section" id="understanding">
<h2>Understanding<a class="headerlink" href="#understanding" title="Permalink to this headline"></a></h2>
<p>In this chapter we will help you understand the <code class="docutils literal"><span class="pre">DocumentManager</span></code>
and the <code class="docutils literal"><span class="pre">UnitOfWork</span></code>. A Unit of Work is similar to an
object-level transaction. A new Unit of Work is implicitly started
when a DocumentManager is initially created or after
<code class="docutils literal"><span class="pre">DocumentManager#flush()</span></code> has been invoked. A Unit of Work is
committed (and a new one started) by invoking
<code class="docutils literal"><span class="pre">DocumentManager#flush()</span></code>.</p>
<p>A Unit of Work can be manually closed by calling
<code class="docutils literal"><span class="pre">DocumentManager#close()</span></code>. Any changes to objects within this
Unit of Work that have not yet been persisted are lost.</p>
<div class="section" id="the-size-of-a-unit-of-work">
<h3>The size of a Unit of Work<a class="headerlink" href="#the-size-of-a-unit-of-work" title="Permalink to this headline"></a></h3>
<p>The size of a Unit of Work mainly refers to the number of managed
documents at a particular point in time.</p>
</div>
<div class="section" id="the-cost-of-flush">
<h3>The cost of flush()<a class="headerlink" href="#the-cost-of-flush" title="Permalink to this headline"></a></h3>
<p>How costly a flush operation is in terms of performance mainly
depends on the size. You can get the size of your Unit of Work as
follows:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$uowSize</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getUnitOfWork</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">size</span><span class="p">();</span>
</pre></div>
</div>
<p>The size represents the number of managed documents in the Unit of
Work. This size affects the performance of flush() operations due
to change tracking and, of course, memory consumption, so you may
want to check it from time to time during development.</p>
<div class="admonition caution">
<p class="first admonition-title">Caution</p>
<p class="last">Do not invoke <code class="docutils literal"><span class="pre">flush</span></code> after every change to a
document or every single invocation of persist/remove/merge/...
This is an anti-pattern and unnecessarily reduces the performance
of your application. Instead, form units of work that operate on
your objects and call <code class="docutils literal"><span class="pre">flush</span></code> when you are done. While serving a
single HTTP request there should be usually no need for invoking
<code class="docutils literal"><span class="pre">flush</span></code> more than 0-2 times.</p>
</div>
</div>
<div class="section" id="direct-access-to-a-unit-of-work">
<h3>Direct access to a Unit of Work<a class="headerlink" href="#direct-access-to-a-unit-of-work" title="Permalink to this headline"></a></h3>
<p>You can get direct access to the Unit of Work by calling
<code class="docutils literal"><span class="pre">DocumentManager#getUnitOfWork()</span></code>. This will return the
UnitOfWork instance the DocumentManager is currently using.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$uow</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getUnitOfWork</span><span class="p">();</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Directly manipulating a UnitOfWork is not recommended.
When working directly with the UnitOfWork API, respect methods
marked as INTERNAL by not using them and carefully read the API
documentation.</p>
</div>
</div>
</div>
<div class="section" id="persisting-documents">
<h2>Persisting documents<a class="headerlink" href="#persisting-documents" title="Permalink to this headline"></a></h2>
<p>A document can be made persistent by passing it to the
<code class="docutils literal"><span class="pre">DocumentManager#persist($document)</span></code> method. By applying the
persist operation on some document, that document becomes MANAGED,
which means that its persistence is from now on managed by an
DocumentManager. As a result the persistent state of such a
document will subsequently be properly synchronized with the
database when <code class="docutils literal"><span class="pre">DocumentManager#flush()</span></code> is invoked.</p>
<div class="admonition caution">
<p class="first admonition-title">Caution</p>
<p class="last">Invoking the <code class="docutils literal"><span class="pre">persist</span></code> method on a document does NOT
cause an immediate insert to be issued on the database. Doctrine
applies a strategy called &quot;transactional write-behind&quot;, which means
that it will delay most operations until
<code class="docutils literal"><span class="pre">DocumentManager#flush()</span></code> is invoked which will then issue all
necessary queries to synchronize your objects with the database in
the most efficient way.</p>
</div>
<p>Example:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$user</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">User</span><span class="p">();</span>
<span class="nv">$user</span><span class="o">-&gt;</span><span class="na">setUsername</span><span class="p">(</span><span class="s1">&#39;jwage&#39;</span><span class="p">);</span>
<span class="nv">$user</span><span class="o">-&gt;</span><span class="na">setPassword</span><span class="p">(</span><span class="s1">&#39;changeme&#39;</span><span class="p">);</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">persist</span><span class="p">(</span><span class="nv">$user</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>
<div class="admonition caution">
<p class="first admonition-title">Caution</p>
<p class="last">The document identifier is generated during <code class="docutils literal"><span class="pre">persist</span></code> if not previously
specified. Users cannot rely on a document identifier being available during
the <code class="docutils literal"><span class="pre">prePersist</span></code> event.</p>
</div>
<p>The semantics of the persist operation, applied on a document X,
are as follows:</p>
<ul class="simple">
<li>If X is a new document, it becomes managed. The document X will be
entered into the database as a result of the flush operation.</li>
<li>If X is a preexisting managed document, it is ignored by the
persist operation. However, the persist operation is cascaded to
documents referenced by X, if the relationships from X to these
other documents are mapped with cascade=PERSIST or cascade=ALL.</li>
<li>If X is a removed document, it becomes managed.</li>
<li>If X is a detached document, the behavior is undefined.</li>
</ul>
<div class="admonition caution">
<p class="first admonition-title">Caution</p>
<p class="last">Do not pass detached documents to the persist operation.</p>
</div>
</div>
<div class="section" id="flush-options">
<span id="id1"></span><h2>Flush Options<a class="headerlink" href="#flush-options" title="Permalink to this headline"></a></h2>
<p>When committing your documents you can specify an array of options to the
<code class="docutils literal"><span class="pre">flush</span></code> method. With it you can send options to the underlying database
like <code class="docutils literal"><span class="pre">safe</span></code>, <code class="docutils literal"><span class="pre">fsync</span></code>, etc.</p>
<p>Example:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$user</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getRepository</span><span class="p">(</span><span class="s1">&#39;User&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">find</span><span class="p">(</span><span class="nv">$userId</span><span class="p">);</span>
<span class="c1">// ...</span>
<span class="nv">$user</span><span class="o">-&gt;</span><span class="na">setPassword</span><span class="p">(</span><span class="s1">&#39;changeme&#39;</span><span class="p">);</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">flush</span><span class="p">(</span><span class="k">null</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span><span class="s1">&#39;safe&#39;</span> <span class="o">=&gt;</span> <span class="k">true</span><span class="p">,</span> <span class="s1">&#39;fsync&#39;</span> <span class="o">=&gt;</span> <span class="k">true</span><span class="p">));</span>
</pre></div>
</div>
<p>You can configure the default flush options on your <code class="docutils literal"><span class="pre">Configuration</span></code> object
if you want to set them globally for all flushes.</p>
<p>Example:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$config</span><span class="o">-&gt;</span><span class="na">setDefaultCommitOptions</span><span class="p">(</span><span class="k">array</span><span class="p">(</span>
<span class="s1">&#39;safe&#39;</span> <span class="o">=&gt;</span> <span class="k">true</span><span class="p">,</span>
<span class="s1">&#39;fsync&#39;</span> <span class="o">=&gt;</span> <span class="k">true</span>
<span class="p">));</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">Safe is set to true by default for all writes when using the ODM.</p>
</div>
</div>
<div class="section" id="removing-documents">
<h2>Removing documents<a class="headerlink" href="#removing-documents" title="Permalink to this headline"></a></h2>
<p>A document can be removed from persistent storage by passing it to
the <code class="docutils literal"><span class="pre">DocumentManager#remove($document)</span></code> method. By applying the
<code class="docutils literal"><span class="pre">remove</span></code> operation on some document, that document becomes
REMOVED, which means that its persistent state will be deleted once
<code class="docutils literal"><span class="pre">DocumentManager#flush()</span></code> is invoked. The in-memory state of a
document is unaffected by the <code class="docutils literal"><span class="pre">remove</span></code> operation.</p>
<div class="admonition caution">
<p class="first admonition-title">Caution</p>
<p class="last">Just like <code class="docutils literal"><span class="pre">persist</span></code>, invoking <code class="docutils literal"><span class="pre">remove</span></code> on a
document does NOT cause an immediate query to be issued on the
database. The document will be removed on the next invocation of
<code class="docutils literal"><span class="pre">DocumentManager#flush()</span></code> that involves that document.</p>
</div>
<p>Example:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">remove</span><span class="p">(</span><span class="nv">$user</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>The semantics of the remove operation, applied to a document X are
as follows:</p>
<ul class="simple">
<li>If X is a new document, it is ignored by the remove operation.
However, the remove operation is cascaded to documents referenced
by X, if the relationship from X to these other documents is mapped
with cascade=REMOVE or cascade=ALL.</li>
<li>If X is a managed document, the remove operation causes it to
become removed. The remove operation is cascaded to documents
referenced by X, if the relationships from X to these other
documents is mapped with cascade=REMOVE or cascade=ALL.</li>
<li>If X is a detached document, an InvalidArgumentException will be
thrown.</li>
<li>If X is a removed document, it is ignored by the remove operation.</li>
<li>A removed document X will be removed from the database as a result
of the flush operation.</li>
</ul>
</div>
<div class="section" id="detaching-documents">
<h2>Detaching documents<a class="headerlink" href="#detaching-documents" title="Permalink to this headline"></a></h2>
<p>A document is detached from a DocumentManager and thus no longer
managed by invoking the <code class="docutils literal"><span class="pre">DocumentManager#detach($document)</span></code>
method on it or by cascading the detach operation to it. Changes
made to the detached document, if any (including removal of the
document), will not be synchronized to the database after the
document has been detached.</p>
<p>Doctrine will not hold on to any references to a detached
document.</p>
<p>Example:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">detach</span><span class="p">(</span><span class="nv">$document</span><span class="p">);</span>
</pre></div>
</div>
<p>The semantics of the detach operation, applied to a document X are
as follows:</p>
<ul class="simple">
<li>If X is a managed document, the detach operation causes it to
become detached. The detach operation is cascaded to documents
referenced by X, if the relationships from X to these other
documents is mapped with cascade=DETACH or cascade=ALL. Documents
which previously referenced X will continue to reference X.</li>
<li>If X is a new or detached document, it is ignored by the detach
operation.</li>
<li>If X is a removed document, the detach operation is cascaded to
documents referenced by X, if the relationships from X to these
other documents is mapped with cascade=DETACH or
cascade=ALL/Documents which previously referenced X will continue
to reference X.</li>
</ul>
<p>There are several situations in which a document is detached
automatically without invoking the <code class="docutils literal"><span class="pre">detach</span></code> method:</p>
<ul class="simple">
<li>When <code class="docutils literal"><span class="pre">DocumentManager#clear()</span></code> is invoked, all documents that are
currently managed by the DocumentManager instance become detached.</li>
<li>When serializing a document. The document retrieved upon subsequent
unserialization will be detached (This is the case for all
documents that are serialized and stored in some cache).</li>
</ul>
<p>The <code class="docutils literal"><span class="pre">detach</span></code> operation is usually not as frequently needed and
used as <code class="docutils literal"><span class="pre">persist</span></code> and <code class="docutils literal"><span class="pre">remove</span></code>.</p>
</div>
<div class="section" id="merging-documents">
<h2>Merging documents<a class="headerlink" href="#merging-documents" title="Permalink to this headline"></a></h2>
<p>Merging documents refers to the merging of (usually detached)
documents into the context of a DocumentManager so that they
become managed again. To merge the state of a document into an
DocumentManager use the <code class="docutils literal"><span class="pre">DocumentManager#merge($document)</span></code>
method. The state of the passed document will be merged into a
managed copy of this document and this copy will subsequently be
returned.</p>
<p>Example:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$detachedDocument</span> <span class="o">=</span> <span class="nb">unserialize</span><span class="p">(</span><span class="nv">$serializedDocument</span><span class="p">);</span> <span class="c1">// some detached document</span>
<span class="nv">$document</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">merge</span><span class="p">(</span><span class="nv">$detachedDocument</span><span class="p">);</span>
<span class="c1">// $document now refers to the fully managed copy returned by the merge operation.</span>
<span class="c1">// The DocumentManager $dm now manages the persistence of $document as usual.</span>
<span class="nx">The</span> <span class="nx">semantics</span> <span class="nx">of</span> <span class="nx">the</span> <span class="nx">merge</span> <span class="nx">operation</span><span class="p">,</span> <span class="nx">applied</span> <span class="nx">to</span> <span class="nx">a</span> <span class="nx">document</span> <span class="nx">X</span><span class="p">,</span> <span class="nx">are</span>
<span class="k">as</span> <span class="nx">follows</span><span class="o">:</span>
</pre></div>
</div>
<ul class="simple">
<li>If X is a detached document, the state of X is copied onto a
pre-existing managed document instance X' of the same iddocument or
a new managed copy X' of X is created.</li>
<li>If X is a new document instance, an InvalidArgumentException will
be thrown.</li>
<li>If X is a removed document instance, an InvalidArgumentException
will be thrown.</li>
<li>If X is a managed document, it is ignored by the merge operation,
however, the merge operation is cascaded to documents referenced by
relationships from X if these relationships have been mapped with
the cascade element value MERGE or ALL.</li>
<li>For all documents Y referenced by relationships from X having the
cascade element value MERGE or ALL, Y is merged recursively as Y'.
For all such Y referenced by X, X' is set to reference Y'. (Note
that if X is managed then X is the same object as X'.)</li>
<li>If X is a document merged to X', with a reference to another
document Y, where cascade=MERGE or cascade=ALL is not specified,
then navigation of the same association from X' yields a reference
to a managed object Y' with the same persistent iddocument as Y.</li>
</ul>
<p>The <code class="docutils literal"><span class="pre">merge</span></code> operation is usually not as frequently needed and
used as <code class="docutils literal"><span class="pre">persist</span></code> and <code class="docutils literal"><span class="pre">remove</span></code>. The most common scenario for
the <code class="docutils literal"><span class="pre">merge</span></code> operation is to reattach documents to an
DocumentManager that come from some cache (and are therefore
detached) and you want to modify and persist such a document.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If you load some detached documents from a cache and you
do not need to persist or delete them or otherwise make use of them
without the need for persistence services there is no need to use
<code class="docutils literal"><span class="pre">merge</span></code>. I.e. you can simply pass detached objects from a cache
directly to the view.</p>
</div>
</div>
<div class="section" id="references">
<h2>References<a class="headerlink" href="#references" title="Permalink to this headline"></a></h2>
<p>References between documents and embedded documents are represented
just like in regular object-oriented PHP, with references to other
objects or collections of objects.</p>
</div>
<div class="section" id="establishing-references">
<h2>Establishing References<a class="headerlink" href="#establishing-references" title="Permalink to this headline"></a></h2>
<p>Establishing a reference to another document is straight forward:</p>
<p>Here is an example where we add a new comment to an article:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$comment</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Comment</span><span class="p">();</span>
<span class="c1">// ...</span>
<span class="nv">$article</span><span class="o">-&gt;</span><span class="na">getComments</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">add</span><span class="p">(</span><span class="nv">$comment</span><span class="p">);</span>
</pre></div>
</div>
<p>Or you can set a single reference:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$address</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Address</span><span class="p">();</span>
<span class="c1">// ...</span>
<span class="nv">$user</span><span class="o">-&gt;</span><span class="na">setAddress</span><span class="p">(</span><span class="nv">$address</span><span class="p">);</span>
</pre></div>
</div>
</div>
<div class="section" id="removing-references">
<h2>Removing References<a class="headerlink" href="#removing-references" title="Permalink to this headline"></a></h2>
<p>Removing an association between two documents is similarly
straight-forward. There are two strategies to do so, by key and by
element. Here are some examples:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$article</span><span class="o">-&gt;</span><span class="na">getComments</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">removeElement</span><span class="p">(</span><span class="nv">$comment</span><span class="p">);</span>
<span class="nv">$article</span><span class="o">-&gt;</span><span class="na">getComments</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">remove</span><span class="p">(</span><span class="nv">$ithComment</span><span class="p">);</span>
</pre></div>
</div>
<p>Or you can remove a single reference:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$user</span><span class="o">-&gt;</span><span class="na">setAddress</span><span class="p">(</span><span class="k">null</span><span class="p">);</span>
</pre></div>
</div>
<p>When working with collections, keep in mind that a Collection is
essentially an ordered map (just like a PHP array). That is why the
<code class="docutils literal"><span class="pre">remove</span></code> operation accepts an index/key. <code class="docutils literal"><span class="pre">removeElement</span></code> is a
separate method that has O(n) complexity, where n is the size of
the map.</p>
</div>
<div class="section" id="transitive-persistence">
<h2>Transitive persistence<a class="headerlink" href="#transitive-persistence" title="Permalink to this headline"></a></h2>
<p>Persisting, removing, detaching and merging individual documents
can become pretty cumbersome, especially when a larger object graph
with collections is involved. Therefore Doctrine provides a
mechanism for transitive persistence through cascading of these
operations. Each reference to another document or a collection of
documents can be configured to automatically cascade certain
operations. By default, no operations are cascaded.</p>
<p>The following cascade options exist:</p>
<ul class="simple">
<li>persist : Cascades persist operations to the associated documents.</li>
<li>remove : Cascades remove operations to the associated documents.</li>
<li>merge : Cascades merge operations to the associated documents.</li>
<li>detach : Cascades detach operations to the associated documents.</li>
<li>all : Cascades persist, remove, merge and detach operations to
associated documents.</li>
</ul>
<p>The following example shows an association to a number of
addresses. If persist() or remove() is invoked on any User
document, it will be cascaded to all associated Address documents
in the $addresses collection.</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</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;Address&quot;, cascade={&quot;persist&quot;, &quot;remove&quot;})</span>
<span class="sd"> */</span>
<span class="k">private</span> <span class="nv">$addresses</span><span class="p">;</span>
<span class="c1">//...</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Even though automatic cascading is convenient it should be used
with care. Do not blindly apply cascade=all to all associations as
it will unnecessarily degrade the performance of your application.</p>
</div>
<div class="section" id="querying">
<h2>Querying<a class="headerlink" href="#querying" title="Permalink to this headline"></a></h2>
<p>Doctrine provides the following ways, in increasing level of power
and flexibility, to query for persistent objects. You should always
start with the simplest one that suits your needs.</p>
<div class="section" id="by-primary-key">
<h3>By Primary Key<a class="headerlink" href="#by-primary-key" title="Permalink to this headline"></a></h3>
<p>The most basic way to query for a persistent object is by its
identifier / primary key using the
<code class="docutils literal"><span class="pre">DocumentManager#find($documentName,</span> <span class="pre">$id)</span></code> method. Here is an
example:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$user</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="s1">&#39;User&#39;</span><span class="p">,</span> <span class="nv">$id</span><span class="p">);</span>
</pre></div>
</div>
<p>The return value is either the found document instance or null if
no instance could be found with the given identifier.</p>
<p>Essentially, <code class="docutils literal"><span class="pre">DocumentManager#find()</span></code> is just a shortcut for the
following:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$user</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getRepository</span><span class="p">(</span><span class="s1">&#39;User&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">find</span><span class="p">(</span><span class="nv">$id</span><span class="p">);</span>
</pre></div>
</div>
<p><code class="docutils literal"><span class="pre">DocumentManager#getRepository($documentName)</span></code> returns a
repository object which provides many ways to retrieve documents of
the specified type. By default, the repository instance is of type
<code class="docutils literal"><span class="pre">Doctrine\ODM\MongoDB\DocumentRepository</span></code>. You can also use
custom repository classes.</p>
</div>
<div class="section" id="by-simple-conditions">
<h3>By Simple Conditions<a class="headerlink" href="#by-simple-conditions" title="Permalink to this headline"></a></h3>
<p>To query for one or more documents based on several conditions that
form a logical conjunction, use the <code class="docutils literal"><span class="pre">findBy</span></code> and <code class="docutils literal"><span class="pre">findOneBy</span></code>
methods on a repository as follows:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="c1">// All users that are 20 years old</span>
<span class="nv">$users</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getRepository</span><span class="p">(</span><span class="s1">&#39;User&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">findBy</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="s1">&#39;age&#39;</span> <span class="o">=&gt;</span> <span class="mi">20</span><span class="p">));</span>
<span class="c1">// All users that are 20 years old and have a surname of &#39;Miller&#39;</span>
<span class="nv">$users</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getRepository</span><span class="p">(</span><span class="s1">&#39;User&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">findBy</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="s1">&#39;age&#39;</span> <span class="o">=&gt;</span> <span class="mi">20</span><span class="p">,</span> <span class="s1">&#39;surname&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;Miller&#39;</span><span class="p">));</span>
<span class="c1">// A single user by its nickname</span>
<span class="nv">$user</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getRepository</span><span class="p">(</span><span class="s1">&#39;User&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">findOneBy</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="s1">&#39;nickname&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;romanb&#39;</span><span class="p">));</span>
</pre></div>
</div>
<p>A DocumentRepository also provides a mechanism for more concise
calls through its use of <code class="docutils literal"><span class="pre">__call</span></code>. Thus, the following two
examples are equivalent:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="c1">// A single user by its nickname</span>
<span class="nv">$user</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getRepository</span><span class="p">(</span><span class="s1">&#39;User&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">findOneBy</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="s1">&#39;nickname&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;romanb&#39;</span><span class="p">));</span>
<span class="c1">// A single user by its nickname (__call magic)</span>
<span class="nv">$user</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">getRepository</span><span class="p">(</span><span class="s1">&#39;User&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">findOneByNickname</span><span class="p">(</span><span class="s1">&#39;romanb&#39;</span><span class="p">);</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">You can learn more about Repositories in a <a class="reference internal" href="document-repositories.html#document-repositories"><span class="std std-ref">dedicated chapter</span></a>.</p>
</div>
</div>
<div class="section" id="by-lazy-loading">
<h3>By Lazy Loading<a class="headerlink" href="#by-lazy-loading" title="Permalink to this headline"></a></h3>
<p>Whenever you have a managed document instance at hand, you can
traverse and use any associations of that document as if they were
in-memory already. Doctrine will automatically load the associated
objects on demand through the concept of lazy-loading.</p>
</div>
<div class="section" id="by-query-builder-objects">
<h3>By Query Builder Objects<a class="headerlink" href="#by-query-builder-objects" title="Permalink to this headline"></a></h3>
<p>The most powerful and flexible method to query for persistent
objects is the QueryBuilder object. The QueryBuilder object enables you to query
for persistent objects with a fluent object oriented interface.</p>
<p>You can create a query using
<code class="docutils literal"><span class="pre">DocumentManager#createQueryBuilder($documentName</span> <span class="pre">=</span> <span class="pre">null)</span></code>. Here is a
simple example:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="c1">// All users with an age between 20 and 30 (inclusive).</span>
<span class="nv">$qb</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;User&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;age&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">range</span><span class="p">(</span><span class="mi">20</span><span class="p">,</span> <span class="mi">30</span><span class="p">);</span>
<span class="nv">$q</span> <span class="o">=</span> <span class="nv">$qb</span><span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">()</span>
<span class="nv">$users</span> <span class="o">=</span> <span class="nv">$q</span><span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
</pre></div>
</div>
</div>
<div class="section" id="by-reference">
<h3>By Reference<a class="headerlink" href="#by-reference" title="Permalink to this headline"></a></h3>
<p>To query documents with a ReferenceOne association to another document, use the <code class="docutils literal"><span class="pre">references($document)</span></code> expression:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$group</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="s1">&#39;Group&#39;</span><span class="p">,</span> <span class="nv">$id</span><span class="p">);</span>
<span class="nv">$usersWithGroup</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;User&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;group&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">references</span><span class="p">(</span><span class="nv">$group</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
</pre></div>
</div>
<p>To find documents with a ReferenceMany association that includes a certain document, use the <code class="docutils literal"><span class="pre">includesReferenceTo($document)</span></code> expression:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$users</span> <span class="o">=</span> <span class="nv">$dm</span><span class="o">-&gt;</span><span class="na">createQueryBuilder</span><span class="p">(</span><span class="s1">&#39;User&#39;</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">field</span><span class="p">(</span><span class="s1">&#39;groups&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">includesReferenceTo</span><span class="p">(</span><span class="nv">$group</span><span class="p">)</span>
<span class="o">-&gt;</span><span class="na">getQuery</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">execute</span><span class="p">();</span>
</pre></div>
</div>
</div>
</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="#">Working with Objects</a><ul>
<li><a class="reference internal" href="#understanding">Understanding</a><ul>
<li><a class="reference internal" href="#the-size-of-a-unit-of-work">The size of a Unit of Work</a></li>
<li><a class="reference internal" href="#the-cost-of-flush">The cost of flush()</a></li>
<li><a class="reference internal" href="#direct-access-to-a-unit-of-work">Direct access to a Unit of Work</a></li>
</ul>
</li>
<li><a class="reference internal" href="#persisting-documents">Persisting documents</a></li>
<li><a class="reference internal" href="#flush-options">Flush Options</a></li>
<li><a class="reference internal" href="#removing-documents">Removing documents</a></li>
<li><a class="reference internal" href="#detaching-documents">Detaching documents</a></li>
<li><a class="reference internal" href="#merging-documents">Merging documents</a></li>
<li><a class="reference internal" href="#references">References</a></li>
<li><a class="reference internal" href="#establishing-references">Establishing References</a></li>
<li><a class="reference internal" href="#removing-references">Removing References</a></li>
<li><a class="reference internal" href="#transitive-persistence">Transitive persistence</a></li>
<li><a class="reference internal" href="#querying">Querying</a><ul>
<li><a class="reference internal" href="#by-primary-key">By Primary Key</a></li>
<li><a class="reference internal" href="#by-simple-conditions">By Simple Conditions</a></li>
<li><a class="reference internal" href="#by-lazy-loading">By Lazy Loading</a></li>
<li><a class="reference internal" href="#by-query-builder-objects">By Query Builder Objects</a></li>
<li><a class="reference internal" href="#by-reference">By Reference</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/working-with-objects.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>
@@ -0,0 +1,317 @@
<!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>XML 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="xml-mapping">
<h1>XML Mapping<a class="headerlink" href="#xml-mapping" title="Permalink to this headline"></a></h1>
<p>The XML mapping driver enables you to provide the ODM metadata in
form of XML documents.</p>
<p>The XML driver is backed by an XML Schema document that describes
the structure of a mapping document. The most recent version of the
XML Schema document is available online at
<a class="reference external" href="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd">http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping.xsd</a>.
The most convenient way to work with XML mapping files is to use an
IDE/editor that can provide code-completion based on such an XML
Schema document. The following is an outline of a XML mapping
document with the proper xmlns/xsi setup for the latest code in
trunk.</p>
<div class="highlight-xml"><div class="highlight"><pre><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;/doctrine-mongo-mapping&gt;</span>
</pre></div>
</div>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">If you do not want to use latest XML Schema document please use link like
<a class="reference external" href="http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping-1.0.0-BETA12.xsd">http://doctrine-project.org/schemas/odm/doctrine-mongo-mapping-1.0.0-BETA12.xsd</a>.
You can change <code class="docutils literal"><span class="pre">1.0.0-BETA12</span></code> part of the URL to
<a class="reference external" href="https://github.com/doctrine/mongodb-odm/releases">any other ODM version</a>.</p>
</div>
<p>The XML mapping document of a class is loaded on-demand the first
time it is requested and subsequently stored in the metadata cache.
In order to work, this requires certain conventions:</p>
<ul class="simple">
<li>Each document/mapped superclass must get its own dedicated XML
mapping document.</li>
<li>The name of the mapping document must consist of the fully
qualified name of the class, where namespace separators are
replaced by dots (.).</li>
<li>All mapping documents should get the extension &quot;.dcm.xml&quot; to
identify it as a Doctrine mapping file. This is more of a
convention and you are not forced to do this. You can change the
file extension easily enough.</li>
</ul>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$driver</span><span class="o">-&gt;</span><span class="na">setFileExtension</span><span class="p">(</span><span class="s1">&#39;.xml&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>It is recommended to put all XML mapping documents in a single
folder but you can spread the documents over several folders if you
want to. In order to tell the XmlDriver where to look for your
mapping documents, supply an array of paths as the first argument
of the constructor, like this:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="c1">// $config instanceof Doctrine\ODM\MongoDB\Configuration</span>
<span class="nv">$driver</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">XmlDriver</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="s1">&#39;/path/to/files&#39;</span><span class="p">));</span>
<span class="nv">$config</span><span class="o">-&gt;</span><span class="na">setMetadataDriverImpl</span><span class="p">(</span><span class="nv">$driver</span><span class="p">);</span>
</pre></div>
</div>
<div class="section" id="simplified-xml-driver">
<h2>Simplified XML Driver<a class="headerlink" href="#simplified-xml-driver" title="Permalink to this headline"></a></h2>
<p>The Symfony project sponsored a driver that simplifies usage of the XML Driver.
The changes between the original driver are:</p>
<ol class="arabic simple">
<li>File Extension is .mongodb-odm.xml</li>
<li>Filenames are shortened, &quot;MyProjectDocumentsUser&quot; will become User.mongodb-odm.xml</li>
<li>You can add a global file and add multiple documents in this file.</li>
</ol>
<p>Configuration of this client works a little bit different:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$namespaces</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span>
<span class="s1">&#39;MyProject\Documents&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;/path/to/files1&#39;</span><span class="p">,</span>
<span class="s1">&#39;OtherProject\Documents&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;/path/to/files2&#39;</span>
<span class="p">);</span>
<span class="nv">$driver</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">\Doctrine\ODM\MongoDB\Mapping\Driver\SimplifiedXmlDriver</span><span class="p">(</span><span class="nv">$namespaces</span><span class="p">);</span>
<span class="nv">$driver</span><span class="o">-&gt;</span><span class="na">setGlobalBasename</span><span class="p">(</span><span class="s1">&#39;global&#39;</span><span class="p">);</span> <span class="c1">// global.mongodb-odm.xml</span>
</pre></div>
</div>
<div class="section" id="example">
<h3>Example<a class="headerlink" href="#example" title="Permalink to this headline"></a></h3>
<p>As a quick start, here is a small example document that makes use
of several common elements:</p>
<div class="highlight-xml"><div class="highlight"><pre>// Documents.User.dcm.xml
<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\User&quot;</span> <span class="na">db=</span><span class="s">&quot;documents&quot;</span> <span class="na">collection=</span><span class="s">&quot;users&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;field</span> <span class="na">fieldName=</span><span class="s">&quot;id&quot;</span> <span class="na">id=</span><span class="s">&quot;true&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;field</span> <span class="na">fieldName=</span><span class="s">&quot;username&quot;</span> <span class="na">name=</span><span class="s">&quot;login&quot;</span> <span class="na">type=</span><span class="s">&quot;string&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;field</span> <span class="na">fieldName=</span><span class="s">&quot;email&quot;</span> <span class="na">type=</span><span class="s">&quot;string&quot;</span> <span class="na">unique=</span><span class="s">&quot;true&quot;</span> <span class="na">order=</span><span class="s">&quot;desc&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;field</span> <span class="na">fieldName=</span><span class="s">&quot;createdAt&quot;</span> <span class="na">type=</span><span class="s">&quot;date&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;indexes&gt;</span>
<span class="nt">&lt;index</span> <span class="na">unique=</span><span class="s">&quot;true&quot;</span> <span class="na">dropDups=</span><span class="s">&quot;true&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;key</span> <span class="na">name=</span><span class="s">&quot;username&quot;</span> <span class="na">order=</span><span class="s">&quot;desc&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;option</span> <span class="na">name=</span><span class="s">&quot;safe&quot;</span> <span class="na">value=</span><span class="s">&quot;true&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/index&gt;</span>
<span class="nt">&lt;/indexes&gt;</span>
<span class="nt">&lt;embed-one</span> <span class="na">target-document=</span><span class="s">&quot;Documents\Address&quot;</span> <span class="na">field=</span><span class="s">&quot;address&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;reference-one</span> <span class="na">target-document=</span><span class="s">&quot;Documents\Profile&quot;</span> <span class="na">field=</span><span class="s">&quot;profile&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;cascade&gt;</span>
<span class="nt">&lt;all</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/cascade&gt;</span>
<span class="nt">&lt;/reference-one&gt;</span>
<span class="nt">&lt;embed-many</span> <span class="na">target-document=</span><span class="s">&quot;Documents\Phonenumber&quot;</span> <span class="na">field=</span><span class="s">&quot;phonenumbers&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;reference-many</span> <span class="na">target-document=</span><span class="s">&quot;Documents\Group&quot;</span> <span class="na">field=</span><span class="s">&quot;groups&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;cascade&gt;</span>
<span class="nt">&lt;all</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/cascade&gt;</span>
<span class="nt">&lt;/reference-many&gt;</span>
<span class="nt">&lt;reference-one</span> <span class="na">target-document=</span><span class="s">&quot;Documents\Account&quot;</span> <span class="na">field=</span><span class="s">&quot;account&quot;</span><span class="nt">&gt;</span>
<span class="nt">&lt;cascade&gt;</span>
<span class="nt">&lt;all</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/cascade&gt;</span>
<span class="nt">&lt;/reference-one&gt;</span>
<span class="nt">&lt;/document&gt;</span>
<span class="nt">&lt;/doctrine-mongo-mapping&gt;</span>
</pre></div>
</div>
<p>Be aware that class-names specified in the XML files should be fully qualified.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last"><code class="docutils literal"><span class="pre">field-name</span></code> is the name of <strong>property in your object</strong> while <code class="docutils literal"><span class="pre">name</span></code> specifies
name of the field <strong>in the database</strong>. Specifying latter is optional and defaults to
<code class="docutils literal"><span class="pre">field-name</span></code> if not set explicitly.</p>
</div>
</div>
<div class="section" id="reference">
<h3>Reference<a class="headerlink" href="#reference" title="Permalink to this headline"></a></h3>
<div class="section" id="lock">
<span id="xml-reference-lock"></span><h4>Lock<a class="headerlink" href="#lock" title="Permalink to this headline"></a></h4>
<p>The field with the <code class="docutils literal"><span class="pre">lock</span></code> attribute will be used to store lock information for <a class="reference internal" href="transactions-and-concurrency.html#transactions-and-concurrency-pessimistic-locking"><span class="std std-ref">pessimistic locking</span></a>.
This is only compatible with the <code class="docutils literal"><span class="pre">int</span></code> field type, and cannot be combined with <code class="docutils literal"><span class="pre">id=&quot;true&quot;</span></code>.</p>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;doctrine-mongo-mapping&gt;</span>
<span class="nt">&lt;field</span> <span class="na">fieldName=</span><span class="s">&quot;lock&quot;</span> <span class="na">lock=</span><span class="s">&quot;true&quot;</span> <span class="na">type=</span><span class="s">&quot;int&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/doctrine-mongo-mapping&gt;</span>
</pre></div>
</div>
</div>
<div class="section" id="version">
<span id="xml-reference-version"></span><h4>Version<a class="headerlink" href="#version" title="Permalink to this headline"></a></h4>
<p>The field with the <code class="docutils literal"><span class="pre">version</span></code> attribute will be used to store version information for <a class="reference internal" href="transactions-and-concurrency.html#transactions-and-concurrency-optimistic-locking"><span class="std std-ref">optimistic locking</span></a>.
This is only compatible with <code class="docutils literal"><span class="pre">int</span></code> and <code class="docutils literal"><span class="pre">date</span></code> field types, and cannot be combined with <code class="docutils literal"><span class="pre">id=&quot;true&quot;</span></code>.</p>
<div class="highlight-xml"><div class="highlight"><pre><span class="nt">&lt;doctrine-mongo-mapping&gt;</span>
<span class="nt">&lt;field</span> <span class="na">fieldName=</span><span class="s">&quot;version&quot;</span> <span class="na">version=</span><span class="s">&quot;true&quot;</span> <span class="na">type=</span><span class="s">&quot;int&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/doctrine-mongo-mapping&gt;</span>
</pre></div>
</div>
<p>By default, Doctrine ODM updates <a class="reference internal" href="embedded-mapping.html#embed-many"><span class="std std-ref">embed-many</span></a> and
<a class="reference internal" href="reference-mapping.html#reference-many"><span class="std std-ref">reference-many</span></a> collections in separate write operations,
which do not bump the document version. Users employing document versioning are
encouraged to use the <a class="reference internal" href="storage-strategies.html#atomic-set"><span class="std std-ref">atomicSet</span></a> or
<a class="reference internal" href="storage-strategies.html#atomic-set-array"><span class="std std-ref">atomicSetArray</span></a> strategies for such collections, which
will ensure that collections are updated in the same write operation as the
versioned parent document.</p>
</div>
</div>
</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="#">XML Mapping</a><ul>
<li><a class="reference internal" href="#simplified-xml-driver">Simplified XML Driver</a><ul>
<li><a class="reference internal" href="#example">Example</a></li>
<li><a class="reference internal" href="#reference">Reference</a><ul>
<li><a class="reference internal" href="#lock">Lock</a></li>
<li><a class="reference internal" href="#version">Version</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/xml-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>
@@ -0,0 +1,342 @@
<!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>YAML 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="yaml-mapping">
<h1>YAML Mapping<a class="headerlink" href="#yaml-mapping" title="Permalink to this headline"></a></h1>
<p>The YAML mapping driver enables you to provide the ODM metadata in
form of YAML documents.</p>
<p>The YAML mapping document of a class is loaded on-demand the first
time it is requested and subsequently stored in the metadata cache.
In order to work, this requires certain conventions:</p>
<ul class="simple">
<li>Each document/mapped superclass must get its own dedicated YAML
mapping document.</li>
<li>The name of the mapping document must consist of the fully
qualified name of the class, where namespace separators are
replaced by dots (.).</li>
<li>All mapping documents should get the extension &quot;.dcm.yml&quot; to
identify it as a Doctrine mapping file. This is more of a
convention and you are not forced to do this. You can change the
file extension easily enough.</li>
<li></li>
</ul>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$driver</span><span class="o">-&gt;</span><span class="na">setFileExtension</span><span class="p">(</span><span class="s1">&#39;.yml&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>It is recommended to put all YAML mapping documents in a single
folder but you can spread the documents over several folders if you
want to. In order to tell the YamlDriver where to look for your
mapping documents, supply an array of paths as the first argument
of the constructor, like this:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="c1">// $config instanceof Doctrine\ODM\MongoDB\Configuration</span>
<span class="nv">$driver</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">YamlDriver</span><span class="p">(</span><span class="k">array</span><span class="p">(</span><span class="s1">&#39;/path/to/files&#39;</span><span class="p">));</span>
<span class="nv">$config</span><span class="o">-&gt;</span><span class="na">setMetadataDriverImpl</span><span class="p">(</span><span class="nv">$driver</span><span class="p">);</span>
</pre></div>
</div>
<div class="section" id="simplified-yaml-driver">
<h2>Simplified YAML Driver<a class="headerlink" href="#simplified-yaml-driver" title="Permalink to this headline"></a></h2>
<p>The Symfony project sponsored a driver that simplifies usage of the YAML Driver.
The changes between the original driver are:</p>
<ol class="arabic simple">
<li>File Extension is .mongodb-odm.yml</li>
<li>Filenames are shortened, &quot;MyProject\Documents\User&quot; will become User.mongodb-odm.yml</li>
<li>You can add a global file and add multiple documents in this file.</li>
</ol>
<p>Configuration of this client works a little bit different:</p>
<div class="highlight-php"><div class="highlight"><pre><span class="cp">&lt;?php</span>
<span class="nv">$namespaces</span> <span class="o">=</span> <span class="k">array</span><span class="p">(</span>
<span class="s1">&#39;/path/to/files1&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;MyProject\Documents&#39;</span><span class="p">,</span>
<span class="s1">&#39;/path/to/files2&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;OtherProject\Documents&#39;</span>
<span class="p">);</span>
<span class="nv">$driver</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">\Doctrine\ODM\MongoDB\Mapping\Driver\SimplifiedYamlDriver</span><span class="p">(</span><span class="nv">$namespaces</span><span class="p">);</span>
<span class="nv">$driver</span><span class="o">-&gt;</span><span class="na">setGlobalBasename</span><span class="p">(</span><span class="s1">&#39;global&#39;</span><span class="p">);</span> <span class="c1">// global.mongodb-odm.yml</span>
</pre></div>
</div>
<div class="section" id="example">
<h3>Example<a class="headerlink" href="#example" title="Permalink to this headline"></a></h3>
<p>As a quick start, here is a small example document that makes use
of several common elements:</p>
<div class="highlight-yaml"><div class="highlight"><pre><span class="c1"># Documents.User.dcm.yml</span>
<span class="l l-Scalar l-Scalar-Plain">Documents\User</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">db</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">documents</span>
<span class="l l-Scalar l-Scalar-Plain">collection</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">user</span>
<span class="l l-Scalar l-Scalar-Plain">fields</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">id</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">id</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
<span class="l l-Scalar l-Scalar-Plain">username</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">name</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">login</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">string</span>
<span class="l l-Scalar l-Scalar-Plain">email</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">unique</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">order</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">desc</span>
<span class="l l-Scalar l-Scalar-Plain">createdAt</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">date</span>
<span class="l l-Scalar l-Scalar-Plain">indexes</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">index1</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">keys</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">username</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">desc</span>
<span class="l l-Scalar l-Scalar-Plain">options</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">unique</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
<span class="l l-Scalar l-Scalar-Plain">dropDups</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
<span class="l l-Scalar l-Scalar-Plain">safe</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
<span class="l l-Scalar l-Scalar-Plain">embedOne</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">address</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\Address</span>
<span class="l l-Scalar l-Scalar-Plain">embedMany</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">phonenumbers</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\Phonenumber</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">profile</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\Profile</span>
<span class="l l-Scalar l-Scalar-Plain">cascade</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">all</span>
<span class="l l-Scalar l-Scalar-Plain">account</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>
<span class="l l-Scalar l-Scalar-Plain">cascade</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">all</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">groups</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\Group</span>
<span class="l l-Scalar l-Scalar-Plain">cascade</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">all</span>
<span class="c1"># Alternative syntax for the exact same example</span>
<span class="c1"># (allows custom key name for embedded document and reference).</span>
<span class="l l-Scalar l-Scalar-Plain">Documents\User</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">db</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">documents</span>
<span class="l l-Scalar l-Scalar-Plain">collection</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">user</span>
<span class="l l-Scalar l-Scalar-Plain">fields</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">id</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">id</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
<span class="l l-Scalar l-Scalar-Plain">username</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">name</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">login</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">string</span>
<span class="l l-Scalar l-Scalar-Plain">email</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">unique</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">order</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">desc</span>
<span class="l l-Scalar l-Scalar-Plain">createdAt</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">date</span>
<span class="l l-Scalar l-Scalar-Plain">address</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">embedded</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</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">one</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\Address</span>
<span class="l l-Scalar l-Scalar-Plain">phonenumbers</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">embedded</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</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">many</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\Phonenumber</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">reference</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</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">one</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\Profile</span>
<span class="l l-Scalar l-Scalar-Plain">cascade</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">all</span>
<span class="l l-Scalar l-Scalar-Plain">account</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">reference</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</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">one</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>
<span class="l l-Scalar l-Scalar-Plain">cascade</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">all</span>
<span class="l l-Scalar l-Scalar-Plain">groups</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">reference</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</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">many</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\Group</span>
<span class="l l-Scalar l-Scalar-Plain">cascade</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">all</span>
<span class="l l-Scalar l-Scalar-Plain">indexes</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">index1</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">keys</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">username</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">desc</span>
<span class="l l-Scalar l-Scalar-Plain">options</span><span class="p p-Indicator">:</span>
<span class="l l-Scalar l-Scalar-Plain">unique</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
<span class="l l-Scalar l-Scalar-Plain">dropDups</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
<span class="l l-Scalar l-Scalar-Plain">safe</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
</pre></div>
</div>
<p>Be aware that class-names specified in the YAML files should be fully qualified.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">The <code class="docutils literal"><span class="pre">name</span></code> property is an optional setting to change name of the field
<strong>in the database</strong>. Specifying it is optional and defaults to the name
of mapped field.</p>
</div>
</div>
<div class="section" id="reference">
<h3>Reference<a class="headerlink" href="#reference" title="Permalink to this headline"></a></h3>
<div class="section" id="lock">
<span id="yml-reference-lock"></span><h4>Lock<a class="headerlink" href="#lock" title="Permalink to this headline"></a></h4>
<p>The field with the <code class="docutils literal"><span class="pre">lock</span></code> property will be used to store lock information for <a class="reference internal" href="transactions-and-concurrency.html#transactions-and-concurrency-pessimistic-locking"><span class="std std-ref">pessimistic locking</span></a>.
This is only compatible with the <code class="docutils literal"><span class="pre">int</span></code> field type, and cannot be combined with <code class="docutils literal"><span class="pre">id:</span> <span class="pre">true</span></code>.</p>
<div class="highlight-yaml"><div class="highlight"><pre><span class="l l-Scalar l-Scalar-Plain">lock</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">int</span>
<span class="l l-Scalar l-Scalar-Plain">lock</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
</pre></div>
</div>
</div>
<div class="section" id="version">
<span id="yml-reference-version"></span><h4>Version<a class="headerlink" href="#version" title="Permalink to this headline"></a></h4>
<p>The field with the <code class="docutils literal"><span class="pre">version</span></code> property will be used to store version information for <a class="reference internal" href="transactions-and-concurrency.html#transactions-and-concurrency-optimistic-locking"><span class="std std-ref">optimistic locking</span></a>.
This is only compatible with <code class="docutils literal"><span class="pre">int</span></code> and <code class="docutils literal"><span class="pre">date</span></code> field types, and cannot be combined with <code class="docutils literal"><span class="pre">id:</span> <span class="pre">true</span></code>.</p>
<div class="highlight-yaml"><div class="highlight"><pre><span class="l l-Scalar l-Scalar-Plain">version</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">int</span>
<span class="l l-Scalar l-Scalar-Plain">version</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">true</span>
</pre></div>
</div>
<p>By default, Doctrine ODM updates <a class="reference internal" href="embedded-mapping.html#embed-many"><span class="std std-ref">embed-many</span></a> and
<a class="reference internal" href="reference-mapping.html#reference-many"><span class="std std-ref">reference-many</span></a> collections in separate write operations,
which do not bump the document version. Users employing document versioning are
encouraged to use the <a class="reference internal" href="storage-strategies.html#atomic-set"><span class="std std-ref">atomicSet</span></a> or
<a class="reference internal" href="storage-strategies.html#atomic-set-array"><span class="std std-ref">atomicSetArray</span></a> strategies for such collections, which
will ensure that collections are updated in the same write operation as the
versioned parent document.</p>
</div>
</div>
</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="#">YAML Mapping</a><ul>
<li><a class="reference internal" href="#simplified-yaml-driver">Simplified YAML Driver</a><ul>
<li><a class="reference internal" href="#example">Example</a></li>
<li><a class="reference internal" href="#reference">Reference</a><ul>
<li><a class="reference internal" href="#lock">Lock</a></li>
<li><a class="reference internal" href="#version">Version</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="../_sources/reference/yml-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>