我想从DBB检索对象(ARTICLE的实例)的属性(COMMENTS)后重新排序。这可能吗?
我的对象是ARTICLE,它链接到COMMENTS(在实体文章中定义为集合)
我知道我可以对存储库进行排序,但是我的注释的顺序取决于许多条件,有些情况不能通过数据库获得。
条件示例:我希望在顶部将其属性show_first设置为true的注释,然后根据其score排序其他注释。
您可以在查询中添加一个隐藏字段,以便按所需的顺序对事物进行排序,这样就无需处理要排序的完整ArrayCollection。
public function findByArticleInOrderOfState()
{
return $this->createQueryBuilder('c')
->select('c')
->addSelect('
CASE
WHEN c.state = :state_new THEN 1
WHEN c.state = :state_viewed THEN 2
WHEN c.state = :state_deleted THEN 3
ELSE 4
END AS HIDDEN order_by
')
->setParameter('state_new', 'new')
->setParameter('state_viewed', 'viewed')
->setParameter('state_deleted', 'deleted')
->orderBy('order_by', 'ASC')
->addOrderBy('c.createdAt', 'ASC')
->getQuery()
->getResults();
}
这将创建一个隐藏字段order_by
,并根据该对象的当前状态进行设置,然后它将按照该隐藏字段的顺序排列,然后按createdAt
。
订购这样的评论实际上没有任何意义,但确实显示了您可以如何做。有了有关实际用例的更多信息,我(希望)能够使工作更接近您的特定需求。
更新
如果您有show_first == 'yes'|'no'
,则可以执行以下操作。
public function findByArticleInOrderOfState()
{
return $this->createQueryBuilder('c')
->select('c')
->addSelect('
CASE
WHEN c.show_first = :show_first THEN 1
ELSE 2
END AS HIDDEN order_by
')
->setParameter('show_first', 'yes')
->orderBy('order_by', 'ASC')
->addOrderBy('c.createdAt', 'ASC')
->getQuery()
->getResults();
}
在getComments()
实体中设置评论的获取者(Article
),以便以所需的顺序获取评论。
public function getComments(){
$iterator = $comments->getIterator();
$iterator->uasort(function ($a, $b) {
// change getProperty() with the field you want to order on
return ($a->getProperty() < $b->getProperty()) ? -1 : 1;
});
$comments= new ArrayCollection(iterator_to_array($iterator));
return $comments;
}
有关详细信息,请访问此帖子"usort" a Doctrine\Common\Collections\ArrayCollection?
对于关联的简单排序,可以使用Doctrine注释。
/**
* @ORM\OneToMany(targetEntity="Comment", mappedBy="article")
* @ORM\OrderBy({"show_first" = "ASC", "score" = "DESC"})
*/
private $comments;
https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/tutorials/ordered-associations.html
实体对象中可能包含以下内容
public function getCommentsActiveLast3()
{
$criteria = Criteria::create();
$criteria->where(Criteria::expr()->eq('status', Comment::STATUS_PUBLISHED));
$criteria->setMaxResults(3);
if ($this->comments) {
return $this->comments->matching($criteria);
}
}