根据没有连接的两个表查询结果

时间:2018-09-28 09:18:49

标签: typo3 typo3-8.x

我要在Query Builder中创建查询,查询至少应该看起来像(加上默认的typo3字段被隐藏,删除等):


    SELECT DISTINCT
        *
    FROM
        domain_model_topic,
        domain_model_post
    WHERE
        domain_model_topic.uid = domain_model_post.topic
            AND (domain_model_topic.title LIKE '%test%'
            OR domain_model_post.text LIKE '%test%')

查询用于在论坛中搜索所选单词 在此查询中,我有一个来自用户的变量:用于在主题和帖子中搜索的文本。

基于https://docs.typo3.org/typo3cms/CoreApiReference/8.7/ApiOverview/Database/QueryBuilder/的文档

我创建了类似的内容:


    /** @var \TYPO3\CMS\Core\Database\Query\QueryBuilder $queryBuilder */
    $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('domain_model_topic');
    $queryBuilder->getRestrictions()->removeAll();
    $queryBuilder
        ->select('*')
        ->from('domain_model_post')
        ->from('domain_model_topic')
        ->where(
            $queryBuilder->expr()
                ->eq('domain_model_topic.uid', 'domain_model_post.topic') . ' AND ' .
            $queryBuilder->expr()
                ->like('domain_model_topic.title', $queryBuilder->createNamedParameter('%' . $queryBuilder->escapeLikeWildcards($search->getSWord()) . '%')) . ' OR ' .
            $queryBuilder->expr()
                ->like('domain_model_post.text', $queryBuilder->createNamedParameter('%' . $queryBuilder->escapeLikeWildcards($search->getSWord()) . '%'))
        );
    $test = $queryBuilder->execute()->fetchAll();

但是此代码会导致错误的Allowed memory size of XXX bytes exhausted分配给任意数量的内存

我尝试重写查询以使其更简单(没有$queryBuilder->expr():


    $queryBuilder
        ->select('*')
        ->from('domain_model_post')
        ->from('domain_model_topic')
        ->where(
    "domain_model_topic.uid = domain_model_post.topic
    AND (domain_model_topic.title LIKE '%" . $variableStringFromUser . "%'
    OR domain_model_post.text LIKE '%" . $variableStringFromUser . "%')"
    );

它可以工作,但是在安全方面存在严重问题,然后我尝试添加$queryBuilder->createNamedParameter($variableStringFromUser) 那没用

我的目标是通过论坛的搜索词为一个表中的主题创建搜索,并从另一个表中发布主题。我不能使用左联接,因为它存在严重的性能问题,并且在mysql中进行了一些测试后,从两个表中进行选择可以提供最佳结果(并在mysql中工作)

我应该怎么做才能以安全的方式(尽可能干净)从typo3_8中的帖子开始创建查询(最好是查询生成器)

1 个答案:

答案 0 :(得分:0)

长时间尝试后,我找到了创建查询的解决方案,该查询可以快速运行。


    $queryBuilder
        ->select('*')
        ->from('domain_model_post')
        ->from('domain_model_topic')
        ->orWhere(
            $queryBuilder->expr()->like('domain_model_topic.title', $queryBuilder->createNamedParameter('%' . $queryBuilder->escapeLikeWildcards($search->getSWord()) . '%')),
            $queryBuilder->expr()
                ->like('domain_model_post.text', $queryBuilder->createNamedParameter('%' . $queryBuilder->escapeLikeWildcards($search->getSWord()) . '%'))
        )
        ->andWhere(
            $queryBuilder->expr()->eq('domain_model_topic.uid', 'domain_model_post.topic')
        );

查询此代码:


    SELECT 
        *
    FROM
        `domain_model_post`,
        `domain_model_topic`
    WHERE
        ((`domain_model_topic`.`title` LIKE '%test%')
            OR (`domain_model_post`.`text` LIKE '%test%'))
            AND (`domain_model_topic`.`uid` = domain_model_post.topic)

它的工作比以前的查询快一百倍。我建议所有人都尝试通过具有可行的fromwhere而非联接的文本来优化搜索