/** * Prime a collection of documents property with an efficient single query instead of * lazily loading each field with a single query. * * @param Iterator $collection * @param string $fieldName * @param Closure|boolean $primer * @param array $hints */ public function primeCollection(Iterator $collection, $fieldName, $primer, array $hints = array()) { $collection = $collection->toArray(); if (!count($collection)) { return; } $collectionMetaData = $this->dm->getClassMetaData(get_class(current($collection))); $fieldMapping = $collectionMetaData->fieldMappings[$fieldName]; $cmd = $this->cmd; $groupedIds = array(); foreach ($collection as $element) { if ($fieldMapping['type'] == 'many') { $fieldValue = $collectionMetaData->getFieldValue($element, $fieldName); if ($fieldValue instanceof PersistentCollection) { foreach ($fieldValue->getMongoData() as $key => $reference) { if (isset($fieldMapping['simple']) && $fieldMapping['simple']) { $className = $fieldMapping['targetDocument']; $mongoId = $reference; } else { $className = $this->dm->getClassNameFromDiscriminatorValue($fieldMapping, $reference); $mongoId = $reference[$cmd . 'id']; } $id = (string) $mongoId; $document = $this->uow->tryGetById($id, $className); if (!$document || $document instanceof Proxy && !$document->__isInitialized__) { if (!isset($groupedIds[$className])) { $groupedIds[$className] = array(); } $groupedIds[$className][] = $mongoId; } } } } else { if ($fieldMapping['type'] == 'one') { $document = $collectionMetaData->getFieldValue($element, $fieldName); if ($document && $document instanceof Proxy && !$document->__isInitialized__) { $class = $this->dm->getClassMetadata(get_class($document)); $groupedIds[$class->name][] = $this->uow->getDocumentIdentifier($document); } } } } foreach ($groupedIds as $className => $ids) { $class = $this->dm->getClassMetadata($className); if ($primer instanceof \Closure) { $primer($this->dm, $className, $fieldName, $ids, $hints); } else { $repository = $this->dm->getRepository($className); $qb = $repository->createQueryBuilder()->field($class->identifier)->in($ids); if (isset($hints[Query::HINT_SLAVE_OKAY])) { $qb->slaveOkay(true); } $query = $qb->getQuery(); $query->execute()->toArray(); } } }