Я использую Symfony 2 PR12 с Doctrine 2 и MySQL. У меня есть база данных, в которой хранятся статьи и просмотры этих статей:
// ...
class Article {
/**
* @orm:Column(type="bigint")
* @orm:Id
* @orm:GeneratedValue
* @var int
*/
protected $id;
/**
* @orm:OneToMany(targetEntity="ArticleView",mappedBy="article")
* @var ArrayCollection
*/
protected $views;
// ...
}
// ...
class ArticleView {
/**
* @orm:Column(type="bigint")
* @orm:Id
* @orm:GeneratedValue
* @var int
*/
protected $id;
/**
* @orm:Column(type="bigint",name="DateRead",nullable=true)
* @var int
*/
protected $viewDate;
/**
* @orm:ManyToOne(targetEntity="Article",inversedBy="views")
* @var Article
*/
protected $article;
// ...
}
Я хочу получить, например, 20 последних просмотренных статей. Моя первая мысль была бы примерно такой:
$qb = ;
$qb->select('a')
->from('Article', 'a')
->join('a.views', 'v')
->orderBy('v.viewDate', 'DESC')
->groupBy('a.id')
->setMaxResults(20)
;
Однако, когда со статьей связано несколько представлений, комбинация упорядочивания / группировки дает непредсказуемые результаты для упорядочивания.
Это ожидаемое поведение для MySQL, так как группировка выполняется перед заказом, и есть рабочие решения этой проблемы с помощью необработанных запросов на http://www.artfulsoftware.com/infotree/mysqlquerytree.php (Агрегаты -> Агрегаты внутри группы). Но я не могу понять, как перевести любое из этих решений на DQL, поскольку, насколько я могу судить, s нет возможности выбирать из подзапросов или выполнять соединения с самоисключением.
Есть идеи, как решить проблему с приемлемой производительностью?