如何通过Doctrine2 querybuilder获取随机行?

时间:2011-06-05 13:01:03

标签: symfony doctrine-orm

到目前为止,我有:

$qb1 = $this->getEntityManager()->createQueryBuilder();
            $qb1->select('s')
                ->from('\My\Entity\Song', 's')
                ->where('s.id <> ?1')
                ->orderBy('RAND()', '')
                ->setMaxResults(1)
                ->setParameters(array(1=>$current->id));

但是,doctrine2并不理解:

Error: Expected end of string, got '('

甚至他们的querybuilder页面上都没有任何内容。你想告诉我php最好的ORM没有随机功能吗?

2 个答案:

答案 0 :(得分:11)

orderBy方法应该接受Song字段用于排序目的(例如's.author'或's.title'),而不是随机值。即使你选择了一个随机字段进行排序,比如在php中随机选择一个,这根本就不是随机的,因为你总是会得到当前排序标准的第一个结果。如果你的歌曲有8个字段,那么你的搜索结果中只会有8首不同的歌曲,即使你有数千个存储。

这是一个建议:

$qb1->select('s')
    ->from('\My\Entity\Song', 's')
    ->where('s.id <> ?1')
    ->setMaxResults(1)
    ->setParameters(array(1=>$current->id))
    ->setFirstResult($offset);

这里,$ offset可以是你通过rand()或mt_rand()函数在php中获得的随机值。当然,$ offset应该小于歌曲的总数。这只是一个建议,有很多方法可以实现这一目标。

恕我直言,我认为Doctrine2是一个非凡的ORM,并没有像它那样先进的东西。我假设你阅读了参考指南的Query Builder部分,但我也建议你阅读DQL部分,它解释了Doctrine查询系统中可用的功能,以及如何制作自己的功能( !)。

答案 1 :(得分:3)

您需要添加自定义DQL函数RAND。对于symfony2框架,您只需添加config:

即可
doctrine:
    orm:
        entity_managers:
            default:
                dql:
                    numeric_functions:
                        rand: DoctrineExtensions\Query\Mysql\Rand

并在composer.json中添加依赖项:

composer require beberlei/DoctrineExtensions

然后,获得100个随机AcmeBundle:Item实体的解决方案将非常简单:

$em = $this->getContainer()->get('doctrine')->getManager();
$messages = $em->createQueryBuilder()
    ->select('i, RAND() AS HIDDEN r')
    ->from('AcmeBundle:Item', 'i')
    ->orderBy('r', 'ASC')
    ->setMaxResults(100)
    ->getQuery()
    ->getResult();
  

注意:这假设您使用的是MySQL或MariaDB后端。对于SQLite或PostGreSQL,您可能需要一个不同的实现类。