您可以使用 Doctrine\ORM\PersistentCollection 的matching function 提供过滤条件,例如:
use Doctrine\Common\Collections\Criteria;
$group = $entityManager->find('Group', $groupId);
$userCollection = $group->getUsers();
$criteria = Criteria::create()
->where(Criteria::expr()->eq("birthday", "1982-02-17"))
->orderBy(array("username" => Criteria::ASC));
$birthdayUsers = $userCollection->matching($criteria);
"matching()" 如果您的关联定义为“EXTRA_LAZY”,则返回 Doctrine\ORM\LazyCriteriaCollection。
你可以用后者分页:
$birthdayUsers->slice($offset, $length);
使用光标分页
在某些情况下,需要使用cursor pagination。您可以按照建议通过扩展 Doctrine\ORM\PersistentCollection 来做到这一点:
public function sliceWithCursor($criteria, $cursorEntity, $length) {
$orderBy = $criteria->getOrderings();
foreach($orderBy as $columnName => $direction) {
if($direction === Criteria::ASC) {
$criteria->andwhere(Criteria::expr()->gte($columnName, $cursorEntity->{$columnName}));
}
else {
$criteria->andwhere(Criteria::expr()->lte($columnName, $cursorEntity->{$columnName}));
}
$criteria->andwhere(Criteria::expr()->eq("id", $cursorEntity->id)); // exclude cursor entity from the results
}
$criteria->orderBy($orderBy));
$criteria->setMaxResults();
return $this->matching($length);
}
基于游标的分页的想法是使用结果行作为起点,而不是偏移量,并获取下一行。正如alternative for using OFFSET 所述,这个想法是用 order by 子句中的条件替换偏移量。