/** * Primes all references for a single document only. This avoids iterating * over the entire cursor when getSingleResult() is called. * * @param object $document */ protected function primeReferencesForSingleResult($document) { if ($this->referencesPrimed || !$this->hydrate || empty($this->primers) || null === $document) { return; } foreach ($this->primers as $fieldName => $primer) { $primer = is_callable($primer) ? $primer : null; $this->referencePrimer->primeReferences($this->class, array($document), $fieldName, $this->unitOfWorkHints, $primer); } }
/** * Prime references */ protected function primeReferences() { if ($this->referencesPrimed || !$this->hydrate || empty($this->primers)) { return; } $this->referencesPrimed = true; foreach ($this->primers as $fieldName => $primer) { $primer = is_callable($primer) ? $primer : null; $this->referencePrimer->primeReferences($this->class, $this, $fieldName, $this->unitOfWorkHints, $primer); } $this->rewind(); }
/** * Execute the query and returns the results. * * @throws \Doctrine\ODM\MongoDB\MongoDBException * @return mixed */ public function execute() { if ($this->isIndexRequired() && !$this->isIndexed()) { throw MongoDBException::queryNotIndexed($this->class->name, $this->getUnindexedFields()); } $results = parent::execute(); if (!$this->hydrate) { return $results; } $uow = $this->dm->getUnitOfWork(); /* A geoNear command returns an ArrayIterator, where each result is an * object with "dis" (computed distance) and "obj" (original document) * properties. If hydration is enabled, eagerly hydrate these results. * * Other commands results are not handled, since their results may not * resemble documents in the collection. */ if ($this->query['type'] === self::TYPE_GEO_NEAR) { foreach ($results as $key => $result) { $document = $result['obj']; if ($this->class->distance !== null) { $document[$this->class->distance] = $result['dis']; } $results[$key] = $uow->getOrCreateDocument($this->class->name, $document, $this->unitOfWorkHints); } $results->reset(); } /* If a single document is returned from a findAndModify command and it * includes the identifier field, attempt hydration. */ if (($this->query['type'] === self::TYPE_FIND_AND_UPDATE || $this->query['type'] === self::TYPE_FIND_AND_REMOVE) && is_array($results) && isset($results['_id'])) { $results = $uow->getOrCreateDocument($this->class->name, $results, $this->unitOfWorkHints); } if (!empty($this->primers)) { $referencePrimer = new ReferencePrimer($this->dm, $uow); foreach ($this->primers as $fieldName => $primer) { $primer = is_callable($primer) ? $primer : null; $documents = $results instanceof Iterator ? $results : array($results); $referencePrimer->primeReferences($this->class, $documents, $fieldName, $this->unitOfWorkHints, $primer); } } return $results; }