Как уже упоминалось, ваш результат не является массивом, а QueryResult
. Просто FYI, можно превратить его в массив, добавив ->toArray()
в конце запроса:
$productsArr = $this->productRepository->findByDetail($category, $properties)->toArray();
Но это не улучшит ситуацию. Есть два возможных вопросов:
переборе все объекты
Преимущество QueryResult
в том, что она отражает только результат запроса, но не решает все объекты уже. Может быть передан QueryResult, например. на виджет Pagination и затем загружать только запрошенные результаты (например, 1-10, 11-20 и т. д.).
Поскольку вы применяете ручную сортировку, все ваши объекты (в зависимости от вашего проекта, это может быть много ...) загружаются.
По-видимому, вы хотите отсортировать товары по их семейству UID?Почему бы не сделать это с функциональностью Extbase в вашем ProductRepository
:
protected $defaultOrderings = array(
'inFamily.uid' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING
);
жадной загрузки вспомогательных объектов
Ваша модель Product
может иметь отношения к другим моделям (эх продукт к категории, продукт в опции и т.д.) , По умолчанию Extbase разрешает все эти отношения при доступе к объектам.
Чтобы предотвратить это, вы можете использовать Lazy Loading для отношений. Это имеет смысл для вспомогательных объектов, которые не используются во всех представлениях. Например. в вашем представлении списка вам нужно только заголовок, изображение и цена вашего продукта, но вам не нужны все варианты продукта.
Для настройки отложенной загрузки для этих суб объектов, вам просто нужно @lazy
аннотацию в модели:
/**
* @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\My\Extension\Domain\Model\ObjectStorageModel>
* @lazy
*/
protected $categories;
/**
* @var \My\Extension\Domain\Model\OtherModel
* @lazy
*/
protected $author;
Ленивая загрузка может иметь некоторые недостатки, например, в определенных ситуациях при проверке объекта, являющегося экземпляром OtherModel
, вы получаете вместо этого объект типа LazyLoadingProxy
. Вы можете обойти большинство этих проблем или, возможно, даже не наткнуться на них в обычных сценариях. Общий обходной путь, если вы действительно зависит от объекта, не будучи LazyLoadingProxy является проверка так:
if ($product->getAuthor() instanceof \TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy) {
$product->getAuthor()->_loadRealInstance();
}
Это гарантирует, что в любом случае у вас есть «реальный» экземпляр объекта.
Пожалуйста, не забудьте очистить системные кеши, когда вы делаете изменения в отношении одной из проблем.
Вероятно, запрос «тяжелый», и после первого использования все еще находится в кеше запросов вашего сервера, поэтому вы получите более быстрые ответы в следующий раз. –
Я не знаком с TYPO3, но переведен на термины Symfony/Doctrine, кажется, вы можете получить список продуктов из базы данных, а затем получить доступ к некоторому отношению внутри цикла ('getInFamily'). Этот _may_ означает, что вы ленивы загружаете эти данные - это значит, что вы увольняете другой запрос базы данных для каждого продукта в цикле. Подсчитайте запущенные запросы или пропустите строку '$ newSortArr' и посмотрите, работает ли цикл быстрее, не делая этого. Можно предположить, что это может быть так. Обычно разрешается путем присоединения к связанному отношению, поэтому он добавляется к набору результатов и не извлекается с помощью ленивой загрузки. – JimL
@MarcB, но запрос выполняется довольно быстро. Только первое использование массива, например, когда я назначаю его другой переменной, принимает длинный – AVisible