I'd like to order only the result of the previous main query.
I want the top 10 most viewed articles then ordered it by "addedAt date" DESC.
I'm aware of functions such as orderBy or even addOrderBy but it's not what I need here or I'm not implementing it correctly.
Example to get the top 2 on 5 articles :
I extract first the most views :
And then orderedIt by addedAt date DESC (most recent) :
My query :
public function findMostViewed($limit=10, $asArray=false)
{
$qb = $this->createQueryBuilder('n')
->orderBy('n.nbViews', 'DESC')
//->addOrderBy('n.addedAt', 'DESC')
->getQuery()
->setMaxResults($limit);
return ($asArray) ? $qb->getResult(Query::HYDRATE_ARRAY) : $qb->getResult();
}
If I knew how to do a preSelectQuery it would have probably solve the problem ...
I thought to an SQL query :
SELECT ...
FROM ...
WHERE id IN(SELECT id FROM News ORDER BY nbViews DESC LIMIT 10)
ORDER BY addedAt DESC
Based on Veve's answer, I changed the WHERE IN condition and managed to make it work.
public function findMostViewed($limit=10, $asArray=false)
{
$subqb = $this->createQueryBuilder('nn')
->orderBy('nn.nbViews', 'DESC')
->getQuery()
->setMaxResults($limit);
$qb = $this->createQueryBuilder('n')
->where('n.id IN (:ids)')
->setParameter('ids', array_values($subqb->getResult()))
->orderBy('n.addedAt', 'DESC')
->getQuery();
return ($asArray) ? $qb->getResult(Query::HYDRATE_ARRAY) : $qb->getResult();
}
Maybe if you use first order by 'n.addedAt', and then 'n.nbViews', like this:
$qb = $this->createQueryBuilder('n')
->orderBy('n.addedAt', 'DESC')
->addOrderBy('n.nbViews', 'DESC')
->getQuery()
->setMaxResults($limit);
You can make a subquery and use it in your main query:
public function findMostViewed($limit=10, $asArray=false)
{
$subqb = $this->createQueryBuilder('nn')
->orderBy('nn.nbViews', 'DESC')
->getQuery()
->setMaxResults($limit);
$qb = $this->createQueryBuilder('n')
->where($qb->expr()->in('n.id', $subqb->getDQL())
->orderBy('n.addedAt', 'DESC')
->getQuery();
return ($asArray) ? $qb->getResult(Query::HYDRATE_ARRAY) : $qb->getResult();
}
Note the use of nn
instead of n
in the subquery.
It is work too. If you add ->setFirstResult( '1' ) to the code's Israel Rodriguez Sanchez works
$qb = $this->createQueryBuilder('n')
->orderBy('n.addedAt', 'DESC')
->addOrderBy('n.nbViews', 'DESC')
->getQuery()
->setFirstResult( '1' )
->setMaxResults($limit);