setMaxResults 在原则查询已连接时无法正常工作



我想编写一个 DQL 查询,该查询选择发布并加入到另一个实体。

这是我的代码:

$dql = '
SELECT p , h ,t ,m 
FROM App:Post p 
LEFT JOIN p.mentions m
LEFT JOIN p.tags t 
LEFT JOIN p.file h 
WHERE p.user
IN (
SELECT f FROM App:User u
JOIN u.followers f
WHERE u.id = :uid
)
OR p.user = :uid ';
$query = $this->getEntityManager()
->createQuery($dql)
->setMaxResults(5)
->setParameters(['uid' => $user->getId()])
->getArrayResult();

但问题是setMaxResults不会限制帖子实体,而是限制标签实体 5.

这是我的两种结果:

1.与设置最大结果(不能正常工作)

2.与设置最大结果(工作正常)

我的代码有什么问题?

这是在没有分页器的情况下使用setMaxResults() 或setFirstResult()时学说中的预期行为

setMaxResults()实际上是在为生成的查询添加一个SQL LIMIT,它不仅会像您期望的那样限制根实体,还会限制查询返回的行。这意味着在联接查询上,它不会执行您想要的操作。

根据第一个和最大结果项目

如果查询包含指定结果限制的提取联接集合,则方法无法按预期工作。"设置最大结果数"会限制数据库结果行数,但是,对于已加入读取的集合,一个根实体可能会出现在许多行中,从而有效地冻结了少于指定数量的结果。

要实现您想要的目标,您可以做的是在查询中使用分页器

$query = $this->getEntityManager()
->createQuery($dql)
->setMaxResults(5)
->setParameters(['uid' => $user->getId()]);
$paginator = new Paginator($query, $fetchJoinCollection = true);
$c = count($paginator);
foreach ($paginator as $post) {
}

从上面的分页器文档链接:

分页原则查询并不像您一开始想象的那么简单。如果您有具有一对多或多对多关联的复杂获取联接方案,则使用数据库供应商的"默认"LIMIT 功能不足以获得正确的结果。

另请注意:

默认情况下,分页扩展插件执行以下步骤来计算正确的结果:

  • 使用关键字执行计数查询DISTINCT
  • 使用DISTINCT执行限制子查询,以查找当前页面上实体的所有 ID。
  • 执行 WHERE IN 查询以获取当前页面的所有结果。

仅当您实际提取联接对多集合时,才需要此行为。您可以通过将 $fetchJoinCollection 标志设置为 false 来禁用此行为;在这种情况下,仅执行 2 个查询,而不是所描述的 3 个查询。我们希望将来能够自动进行检测。

类似的问题

我建议直接在数据库上运行此查询(有限制)。您将看到查询返回 5 行,但只有 3 个唯一帖子。这是因为一个帖子可能有多个标签,因此帖子标签的每个组合都会产生一行。因此,2 个帖子,每个帖子有 3 个标签,将产生 6 行。设置限制会影响查询返回的行数,它不会神奇地限制仅帖子计数。将查询结果映射到对象时,将删除查询结果中的重复帖子,但此时您只有 3 个唯一的帖子。

您可能应该单独查询帖子和标签,而不是使用具有一对多或多对多关系的limit

最新更新