php Symfony Doctrine Querybuilder -只选择一对多关系中有序连接的第一行

gstyhher  于 9个月前  发布在  PHP
关注(0)|答案(1)|浏览(70)

让我们假设我有实体UserComment处于一对多关系。假设在模型中正确设置了关系,在User模型中称为comments。假设Comment有一个字段text,它是写在注解中的文本。
每个Comment属于一个User,但每个User可以有任意数量的注解(包括根本没有注解)。
我用的是Doctrine-ORM 2.7我需要选择User数据,如果存在,只选择他们最近评论的text。我真的在努力拼凑如何做到这一点。到目前为止我的想法:

  • 该查询应该使用用户ID上的CommentleftJoin()User。我想我想要一个LEFT JOIN,因为这样用户没有任何意见仍然被选中。
  • Comments部分需要是一个嵌套查询,它对具有该用户ID的注解执行类似ORDER BY id DESC LIMIT 1的操作,以便只选择最近的一个。
  • 我不认为我可以使用groupBy(),因为我需要选择最近评论的text,但我可能会通过这里得到MAX(comment.id),这可能会派上用场?

目前为止,我的一次尝试进展如下:

$qb = $em->getRepository(User::class)
         ->createQueryBuilder('u')
         ->select('u.id, u.username') // ...etc. user data
         ->addSelect('c.text') // comment text
         ->leftJoin('u.comments', 'c', 'WITH', ....) // Place nested subquery here somehow?
         ->getQuery()
         ->getArrayResult();

我觉得嵌套查询应该是这样的:

$qb = $em->getRepository(Comment::class)
         ->createQueryBuilder('c')
         ->select('c.id')
         ->where('c.user', ':user')
         ->orderBy('id', 'desc')
         ->getQuery()
         ->getScalarResult();

这是一个虚构的例子;在真实的应用程序中,优化是一个关注点,因此我希望最小化执行的嵌套查询的数量。This answer似乎有一个很好的原始SQL方法,但我对如何将其转换为查询构建器语法感到困惑。如果你能帮忙的话,我将不胜感激。

3qpi33ja

3qpi33ja1#

不知道我是否有你正在寻找的东西,但我想我只是面临着类似的问题。
下面是我提出的查询:

$users = $this->getEntityManager()
        ->getRepository(User::class)
        ->createQueryBuilder('u')
        ->select('u.id')
        ->addSelect('c.id AS c_id', 'c.text')
        ->join('u.pub', 'c')
        ->getQuery()
        ->getResult();

你仍然需要过滤最新的评论。
它为我的目的工作,虽然它给出了一个响应,看起来像这样:

"id": 1,
    "c_id": 1,
    "text": "...",

而不是这样:

"id": 1,
    "c": {
        "id": 1,
        "text": "..."
}

但那不是问题
编辑1:刚刚尝试使用它与一对多,它返回一个完整的用户对象的每一个评论。我还是要把锥子留在这里,可能会有点用。
编辑2:或者你可以使用DTO(数据传输对象)?或者这对你的需求来说太慢了?

相关问题