2015-04-08 2 views
4

У меня есть два объектаDoctrine2, упорядочивание лиц путем подсчета многие ко многим собственности

  • Статья
  • Пользователь

Статья имеет отношение к пользователю с именем «likedByUsers»

Теперь я хотел бы получить порядок статей по количеству понравившихся, но:

  • Я не хочу иметь свойство 'numberOfLikes', потому что это слишком большая проблема, чтобы его обновить.
  • У меня слишком много статей (100k +), чтобы быть реалистичным для «сортировки» на стороне PHP (и тот факт, что мы «вновь достигнув предела делать то причина, почему я задаю этот вопрос)
  • Я могу жить с не получаю количество подобных в возвращаемых значений (как сериализатору позже гидрат его)

что у меня есть:

$builder = $this->createQueryBuilder('a'); 
    ->select('COUNT(u) AS nbrLikes') 
    ->leftJoin('a.likedByUsers', 'u') 
    ->orderBy('nbrLikes', 'DESC') 
    ->groupBy('a.id') 
    ->getQuery() 
    ->getResult() 
; 

это правильно возвращает число подобных (с 0 статей без подобных), но он не возвращает Статьи сами

Я попытался добавить

->select('a, COUNT(u) AS HIDDEN nbrLikes') 

но терпит неудачу, потому a не является частью GROUP BY

любые идеи?

ответ

6

Если вы хотите выбрать «несколько» значений, вам нужно указать их в качестве метода построения запросов. Точно также, как сообщается ниже

$builder = $this->createQueryBuilder('a') 
     ->select('COUNT(u) AS HIDDEN nbrLikes', 'a.id') 
     ->leftJoin('a.likedByUsers', 'u') 
     ->orderBy('nbrLikes', 'DESC') 
     ->groupBy('a.id') 
     ->getQuery() 
     ->getResult(); 

Вы должны помнить, что результат не будет объект, но ассоциативный массив


Если вы хотите полную сущность

$builder = $this->createQueryBuilder('a') 
     ->select('COUNT(u) AS HIDDEN nbrLikes', 'a') 
     ->leftJoin('a.likedByUsers', 'u') 
     ->orderBy('nbrLikes', 'DESC') 
     ->groupBy('a') 
     ->getQuery() 
     ->getResult(); 
+0

Я уже пробовал, это не работает –

+0

ОШИБКА: столбец \ "a2_.title \ "должно появиться в предложении GROUP BY или использоваться в агрегированной функции –

+1

@ user1185460: вы уверены, что добавляете только« a.id », а не целое« a »? Потому что, конечно, если вы добавите целая сущность, все поля должны быть перечислены в функцию groupBy. Это не ограничение Symfony2 или Doctrine2, это SQL-код. – DonCallisto

0

Вы можете взглянуть на 2 функции:

->addSelect 

Which (я считаю) не будет работать при создании QueryBuilder, но их следует использовать с ниже способом.

Вы также можете использовать строитель базового запроса таким образом:

$query = $this->getEntityManager()->createQueryBuilder() 
     ->select('article, nbrLikes, ...') 
     ->from('BundleName:ClassName', 'article') 
     ->leftJoin('article.likedByUsers', 'nbrLikes') 

Это всегда будет выбирать и заселить сущности в избранном. Вы также можете сделать частичный выбор, чтобы избежать получения необходимых полей. Это определенно не решение, но может указывать на вас в правильном направлении.