Для отображения связанных статей на веб-сайте мне нужна функция Cast ().
Мой запрос выглядит так:
SELECT
*,
(CAST(a.uploader = ?1 AS UNSIGNED)
+ CAST(a.param2 = ?2 AS UNSIGNED)
...
) AS matches_count
FROM articles AS a
ORDER BY matches_count DESC
Подсчитывает совпадения и сортирует по наибольшему количеству match_counts.
Проблема в том, что в доктрине нет встроенной функции Cast ().
После нескольких часов проб и ошибок я обнаружил уже доступную пользовательскую функцию DQL:
https://github.com/beberlei/DoctrineExtensions/blob/master/src/Query/Mysql/Cast.php
Я зарегистрировал это в моем doctrine.yml.
Но это не работает, потому что ожидает Cast(X AS Y)
, а не Cast(Y $comparisonOperator X)
.
Когда я использую это в моем хранилище, например:
$this->createQueryBuilder('a, (CAST(author=25 AS UNSIGNED) AS matches_count)')
->getQuery()
->getResult()
;
Я получаю эту ошибку, потому что она не ожидает оператора сравнения:
[Syntax Error] line 0, col 29: Error: Expected Doctrine\ORM\Query\Lexer::T_AS, got '='
Вы знаете, как, возможно, расширить этот класс, а не Cast(Y $comparisonOperator X)
вместо Cast(X AS Y)
?
Я не нашел решения в интернете и пробовал его часами.
Заранее спасибо, что нашли время написать ответ!
Обновление:
Я изменил строку 37 в вышеупомянутом пользовательском классе DQL для Cast:
//old
//$this->fieldIdentifierExpression = $parser->SimpleArithmeticExpression();
//new
$this->fieldIdentifierExpression = $parser->ComparisonExpression();
и как создать запрос:
$this->createQueryBuilder('a')
->select('a, (CAST(a.averageRating=:averageRating AS UNSIGNED) + CAST(a.author=:author AS UNSIGNED)) AS matches_count')
->setParameter('averageRating', $averageRating)
->setParameter('author', $author)
->orderBy('matches_count', 'DESC')
->getQuery()
->getResult();
и это похоже на то!
Я надеюсь, что это правильный способ, это поможет кому-то, и это лучший способ для этой цели.
Чтобы повысить производительность позже, я планирую кэшировать 10 идентификаторов рекомендуемых статей для каждой отдельной страницы статьи в свою собственную таблицу.
Так что не нужно делать расчеты при загрузке страницы.
Этот стол можно воссоздавать каждые 24 часа с помощью cronjob.
ID | recommended_article_ids | article_id
1 | 10,24,76,88| 5
Отзывы и советы очень ценятся!