запрос с результатом на основе двух таблиц без объединения - PullRequest
0 голосов
/ 28 сентября 2018

Я хочу создать запрос в 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 голосов
/ 01 октября 2018

После долгих попыток я нашел решение для создания запроса, который работает быстро.


    $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)

его работа в сто раз быстрее, чем предыдущий запрос.Я рекомендую всем попробовать оптимизировать поиск по тексту с помощью выполнимых from и where вместо объединения

...