php 当Doctrine查询具有连接时,setMaxResults无法正常工作

jtoj6r0c  于 2023-03-07  发布在  PHP
关注(0)|答案(3)|浏览(129)

我想写一个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.with setMaxResults (Not work fine)
2.with setMaxResults (Work fine)
我的代码有什么问题?

5ktev3wc

5ktev3wc1#

    • 这是在使用setMaxResults()setFirstResult()**而不使用分页器时的预期行为。
    • setMaxResults()实际上是向生成的查询添加SQL LIMIT**,它不仅会限制根实体,而且会限制查询返回的行。这意味着在联接查询上,它不会执行您想要的操作。

根据第一个和最大结果项
如果查询包含指定结果限制的提取联接集合,则方法未按预期工作。"设置最大结果数"会限制数据库结果行数,但在提取联接集合的情况下,一个根实体可能会出现在许多行中,从而有效地水合了少于指定结果数的结果。
要实现您想要的结果,您可以在查询中使用Paginator

$query = $this->getEntityManager()
    ->createQuery($dql)
    ->setMaxResults(5)
    ->setParameters(['uid' => $user->getId()]);
$paginator = new Paginator($query, $fetchJoinCollection = true);

$c = count($paginator);
foreach ($paginator as $post) {

}

从上面的Paginator文档链接:
对Doctrine查询分页并不像您一开始想象的那么简单。如果您有复杂的提取连接方案,其中包含一对多或多对多关联,则使用数据库供应商的"默认" LIMIT功能不足以获得正确的结果。
另外,请注意:
默认情况下,分页扩展执行以下步骤来计算正确的结果:

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

这个行为只有在你实际获取一个对多集合的连接时才是必要的。你可以通过设置$fetchJoinCollection标志为false来禁用这个行为;在这种情况下,只执行了2个查询而不是所描述的3个查询。2我们希望将来能自动检测这种情况。
Similar question

ejk8hzay

ejk8hzay2#

我建议运行以下查询(有限制)。您将看到查询返回5行,但只有3个唯一的帖子。这是因为一个帖子可能有多个标签,所以每个帖子标签组合将产生一行。所以2个帖子,每个帖子有3个标签,将产生6行。设置限制将影响查询返回的行数,它不会神奇地只限制帖子数量。2查询结果中重复帖子在Map查询结果到对象时会被删除,但此时你只有3个唯一的帖子。
您可能应该分别查询帖子和标签,而不是将limit与一对多或多对多关系一起使用。

8cdiaqws

8cdiaqws3#

面对同样的问题
我想2条(与标准)由2条(分页),并加入他们的意见
使用mysql意味着不能使用WHERE columnName IN(SELECT * FROM tableName LIMIT X)where-in子查询不能包含LIMIT。
那么,我们应该如何仅为查询的一部分设置最大结果呢?
限制2篇文章的结果返回与一些标准加入他们的评论
如果我按文章分组,我会得到我的两篇文章,但不是所有的评论。
如果我设置了完整查询的最大结果,我得到了2条评论,但第二篇文章不见了。
如果在子查询上设置了setMaxResult,则会限制完整的请求结果。
我想与他们所有的评论选择2篇文章。DQL,QueryBuilder,分页器不能帮助太多这样做...或者它真的不是开发友好。

相关问题