Это ожидаемое поведение в доктрине при использовании setMaxResults () или setFirstResult () без пагинатора.
setMaxResults () фактически добавляет SQL LIMIT к произведенному запросу, он не будет ограничивать только корневую сущность, как вы ожидаете, но строки, возвращаемые запросом. Это означает, что при соединении запросов он не будет делать то, что вы хотите.
В соответствии с Первый и Макс. Пункты результата
Если ваш запрос содержит коллекцию с выборкой, указывающую, что методы ограничения результата не работают так, как вы ожидаете. Задать максимальное количество результатов ограничивает число строк результатов базы данных, однако в случае сборок с выборкой одна корневая сущность может появиться во многих строках, эффективно увлажняя меньше указанного количества результатов.
Что вы можете сделать, чтобы достичь желаемого, это использовать Paginator по вашему запросу:
$query = $this->getEntityManager()
->createQuery($dql)
->setMaxResults(5)
->setParameters(['uid' => $user->getId()]);
$paginator = new Paginator($query, $fetchJoinCollection = true);
$c = count($paginator);
foreach ($paginator as $post) {
}
Из ссылки на документацию Paginator выше:
Запросы на страницы в доктрине не так просты, как вы могли подумать в начале. Если у вас есть сложные сценарии выборки-соединения с однозначными или многозначными связями, использование функциональности LIMIT «по умолчанию» поставщиков баз данных недостаточно для получения правильных результатов.
Также обратите внимание, что:
По умолчанию расширение пагинации выполняет следующие шаги для вычисления правильного результата:
- Выполните запрос Count, используя ключевое слово
DISTINCT
.
- Выполните лимитный подзапрос с помощью
DISTINCT
, чтобы найти все идентификаторы объекта на текущей странице.
- Выполните запрос WHERE IN, чтобы получить все результаты для текущей страницы.
Это поведение необходимо, только если вы на самом деле получаете присоединение к коллекции «многие». Вы можете отключить это поведение, установив для флага $ fetchJoinCollection значение false; в этом случае выполняется только 2 вместо 3 описанных запросов. Мы надеемся автоматизировать обнаружение этого в будущем.
Аналогичный вопрос