Yas*_*984 32 php dql doctrine-orm
以下是我在数据库中查询某些单词的方法
$query = $qb->select('w')
->from('DbEntities\Entity\Word', 'w')
->where('w.indictionary = 0 AND w.frequency > 3')
->orderBy('w.frequency', 'DESC')
->getQuery()
->setMaxResults(100);
Run Code Online (Sandbox Code Playgroud)
我正在使用mysql,我想获得符合条件的随机行,我会在查询中使用rand()命令.
我发现这个类似的问题基本上表明,因为在学说中不支持ORDER BY RAND,你可以随机化主键.但是,这不能在我的情况下完成,因为我有一个搜索条件和一个where子句,以便不是每个主键都满足该条件.
我还发现了一个代码片段,建议你使用OFFSET随机化行,如下所示:
$userCount = Doctrine::getTable('User')
->createQuery()
->select('count(*)')
->fetchOne(array(), Doctrine::HYDRATE_NONE);
$user = Doctrine::getTable('User')
->createQuery()
->limit(1)
->offset(rand(0, $userCount[0] - 1))
->fetchOne();
Run Code Online (Sandbox Code Playgroud)
我有点困惑的是,这是否会帮助我解决在我的情况下随机缺乏对订单的支持.我无法在setMaxResult之后添加偏移量.
知道如何实现这一目标吗?
Ben*_*min 42
Doctrine团队不愿意实现此功能.
您的问题有几种解决方案,每种解决方案都有其自身的缺点:
WHERE x.id IN(?)加载关联的对象,方法是将ID数组作为参数传递.ORDER BY RAND()存在之外的其他原始SQL技术,我不会在这里详细说明,您将在此网站上找到一些好的资源).HMa*_*gdy 31
跟着这些步骤:
在项目中定义一个新类:
namespace My\Custom\Doctrine2\Function;
use Doctrine\ORM\Query\Lexer;
class Rand extends \Doctrine\ORM\Query\AST\Functions\FunctionNode
{
public function parse(\Doctrine\ORM\Query\Parser $parser)
{
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{
return 'RAND()';
}
}
Run Code Online (Sandbox Code Playgroud)
注册课程 config.yml:
doctrine:
orm:
dql:
numeric_functions:
Rand: My\Custom\Doctrine2\Function\Rand
Run Code Online (Sandbox Code Playgroud)
直接使用它:
$qb->addSelect('RAND() as HIDDEN rand')->orderBy('rand');
Run Code Online (Sandbox Code Playgroud)
Jon*_*nny 19
根据Hassan Magdy Saad的建议,您可以使用流行的DoctrineExtensions库:
请参阅此处的mysql实现:https://github.com/beberlei/DoctrineExtensions/blob/master/src/Query/Mysql/Rand.php
# config.yml
doctrine:
orm:
dql:
numeric_functions:
rand: DoctrineExtensions\Query\Mysql\Rand
Run Code Online (Sandbox Code Playgroud)
在Doctrine ORM 2.6.x-dev中测试,您可以实际执行:
->orderBy('RAND()')
Run Code Online (Sandbox Code Playgroud)
小智 9
或者你可以这样做 - >
$words = $em->getRepository('Entity\Word')->findAll();
shuffle($words);
Run Code Online (Sandbox Code Playgroud)
当然,如果您有许多记录,这将是非常低效的,因此请谨慎使用.
为什么不使用存储库?
<?php
namespace Project\ProductsBundle\Entity;
use Doctrine\ORM;
class ProductRepository extends ORM\EntityRepository
{
/**
* @param int $amount
* @return Product[]
*/
public function getRandomProducts($amount = 7)
{
return $this->getRandomProductsNativeQuery($amount)->getResult();
}
/**
* @param int $amount
* @return ORM\NativeQuery
*/
public function getRandomProductsNativeQuery($amount = 7)
{
# set entity name
$table = $this->getClassMetadata()
->getTableName();
# create rsm object
$rsm = new ORM\Query\ResultSetMapping();
$rsm->addEntityResult($this->getEntityName(), 'p');
$rsm->addFieldResult('p', 'id', 'id');
# make query
return $this->getEntityManager()->createNativeQuery("
SELECT p.id FROM {$table} p ORDER BY RAND() LIMIT 0, {$amount}
", $rsm);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
47733 次 |
| 最近记录: |