Select 使用 extbase 的 QueryBuilder 随机记录

Select records at random using extbase's QueryBuilder

我正在为 TYPO3 版本 8 开发定制扩展。

在我的扩展程序中,我想在前端以随机顺序显示至少十个左右的结果集中的三个项目。

举个例子 (Select随机只传三个人给一个view)

我的第一个想法是查看 QueryBuilder 并创建自定义查询。查看其他类似的帖子,似乎 extbase 的查询构建器没有携带 RAND 函数(有充分的理由)。

看看使用 Fluid 和迭代器 viewhelper 来帮助我以随机顺序显示项目会更好吗?还是可以使用QueryBuilder来实现?

我认为 TYPO3、Fluid 或 QueryBuilder 中没有构建方法来执行此操作。我解决它的方式取决于总共有多少条记录。

如果只有几十个,我可能会 select 全部并使用 PHP shuffle 函数对它们进行随机排序,然后显示前 3 个。

如果可以有数百条或更多条记录,我可能会进行计数并得到 0 和计数结果之间的 3 个随机数。然后,您可以使用 setFirstResult(随机数)和 setMaxResults (1) 函数执行 3 个不同的查询。

Extbase 存储库查询没有任何随机函数。至少自 TYPO3 8 LTS 以来新的 Doctrine Querybuilder 可以用来获得随机结果:https://docs.typo3.org/typo3cms/CoreApiReference/latest/ApiOverview/Database/QueryBuilder/Index.html

在此 QueryBuilder 上,您可以使用 addSelectLiteral 将 RAND() 函数插入数据库查询。但是你必须确保你的数据库软件支持这个功能因为TYPO3数据库可以连接到任何其他可能不支持RAND()的数据库软件。

用法示例:

$rows = $queryBuilder
        ->select('*')
        ->from('tx_yourext_domain_model_example')
        ->addSelectLiteral('RAND() AS randomnumber')
        ->orderBy('randomnumber')
        ->setMaxResults(3)
        ->execute()
        ->fetchAll();

要根据结果创建一些 Extbase 模型记录,您可以使用 DataMapper。

$dataMapper = GeneralUtility::makeInstance(TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMapper::class);
$result = $dataMapper->map(\You\Yourext\Model\Example::class, $rows);

我没有在 TYPO3v9 中使用 vhs。我使用秒数和简单的数学来获得 1 个随机元素。比如我从{news}数组中获取迭代器的随机值是通过:

<f:variable name="sec4random" value="{f:format.date(date:'0 seconds', format:'s')}"/>
<f:variable name="count4random" value="{f:count(subject: news)}"/>
Random index for iterator: {sec4random % count4random} 

要使用找到的索引访问 newsItem,您可以添加以下内容:

 <f:variable name="newsindex" value="{sec4random % count4random}"/>
 <f:variable name="newsItem" value="{news.{newsindex}}"/>

现在 {newsItem} 包含来自 {news} 数组的随机单个新闻。