CakePhp 3 — Как сделать заказ по сумме в содержании результата

Я работаю над проектом CakePhp 3, и мне нужно отсортировать комментарии по статьям по сумме голосов по каждому комментарию.

Модели:

  • статьи
  • ArticlesComments
  • ArticlesCommentsVotes
  • пользователей

Пользователь связан с каждой моделью. ArticlesComments имеет идентификатор статьи. ArticlesCommentsVotes имеет comment_id и user_id.

Что мне нужно:

  • Общее количество положительных отзывов
  • Общее количество отрицательных комментариев
  • Сортировать по № Положительные комментарии
  • Сортировать по количеству отрицательных комментариев

Как-то мне удалось получить Total no. положительных и отрицательных комментариев, но CakePhp не позволил бы мне сортировать по количеству комментариев.

Вот мой запрос:

$article = $this->Articles->get($id, [
'contain' => [
'Categories',
'Clusters',
'Tags',
'ArticlesSteps',
'PositiveVotes'    => function ($a){
return $a->select(['PositiveVotes.article_id', 'votes' => 'COUNT(*)']);
},
'NegativeVotes'    => function ($a){
return $a->select(['NegativeVotes.article_id', 'votes' => 'COUNT(*)']);
},
'ArticlesComments' => function ($q){
return $q->contain([
'Users'                 => function ($q){
return $q->select(['username']);
},
'CommentVote'           => function ($q){
return $q->select(['vote']);
},
'CommentsPositiveVotes' => function ($q){
return $q->select(['CommentsPositiveVotes.comment_id', 'positive' => 'SUM(vote)'])->group('comment_id');
},
'CommentsNegativeVotes' => function ($a){
return $a->select(['CommentsNegativeVotes.comment_id', 'CommentsNegativeVotes.user_id']);
}
]);
}
]
]);

Любая помощь приветствуется 🙂

2

Решение

Я думаю, вы не можете отсортировать результаты запроса. Но в вашем случае было бы целесообразно использовать что-то под названием «CounterCache».

http://book.cakephp.org/3.0/en/orm/behaviors/counter-cache.html

0

Другие решения

Я нашел способ это исправить. Мне нужно использовать левый Join для этого. Вот мой обновленный код:

       // Search comments
$comments = $this->ArticlesComments->find()->where([
'ArticlesComments.article_id' => $articleId,
])->contain([
'CommentVote' => function ($q){
return $q->select(['vote']);
},
'Users'       => function ($q){
return $q->select(['username']);
},
]);

// Left Join with ArticlesComments
$comments
->leftJoin(
['ArticlesCommentsVotes' => 'articles_comments_votes'],
['ArticlesComments.id = ArticlesCommentsVotes.comment_id']
);


// Case
$ratingCases = $comments->newExpr()->addCase([
$comments->newExpr()->add(['ArticlesCommentsVotes.vote' => '1']),
$comments->newExpr()->add(['ArticlesCommentsVotes.vote' => '0'])
], [1, - 1, 0], ['integer','integer','integer']);

// Calculate rating and sort
$comments->select(['rating' => $comments->func()->sum($ratingCases)])
->group('ArticlesCommentsVotes.comment_id')->order($sortBy . ' ' . $sortOrder)->autoFields(true);
0