Добавьте несколько полей счетчика содержащейся модели для запроса в cakephp 3

Я хочу иметь в своей модели вместо полного набора записей моделей, содержащихся в другой, только их количество. Я мог бы сделать это, добавив поле «размер» в набор результатов, но я хотел бы сделать это в запросе, так как я хочу динамически разбивать на страницы и упорядочивать результаты. Я использую этот код, но по какой-то причине, если первый счетчик отличен от нуля, оба поля счетчика имеют одинаковое значение, которое является значением второго поля счетчика.

$query = $this->Users->find('all')
            ->contain(['Likes','Favs']);

 $query
      ->select(['like_count' => $query->func()->count('Likes.id')])
      ->leftJoinWith('Likes')
      ->group(['Users.id'])
      ->autoFields(true);

 $query
     ->select(['fav_count' => $query->func()->count('Favs.id')])
     ->leftJoinWith('Favs')
     ->group(['Users.id'])
     ->autoFields(true);

$this->paginate['sortWhitelist'] = [
            'name',
            'email',
            'last_login',
            'fav_count',
            'like_count',
        ];

Я хотел бы знать, почему это происходит, и есть ли какой-либо другой способ сделать то, что я пытаюсь сделать, а именно иметь («имя», адрес электронной почты, «last_login», количество записей в «Нравится» с идентификатором пользователя, количество записей в Favs с идентификатором пользователя). Я попытался использовать функцию join() для левого соединения, но мне не удалось получить желаемый результат.

Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
0
0
269
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если у вас есть несколько объединений, вам нужно считать с помощью DISTINCT, например:

COUNT(DISTINCT Likes.id)

Это связано с тем, что ваш результат будет содержать Likes * Favs количество строк, так как для каждого объединенного лайка будут объединены все избранные, то есть для 2 лайков и 10 избранного вы получите всего 20 строк. Обычный COUNT() будет включать каждую из этих строк.

Также обратите внимание, что вам не нужно повторять всю эту группировку и т. д., И вы можете использовать вызываемый объект для select(), чтобы не разбивать конструктор.

$query = $this->Users
    ->find('all')
    ->select(function (\Cake\ORM\Query $query) {
        return [
            'like_count' => $query->func()->count(
                $query->func()->distinct(['Likes.id' => 'identifier'])
            ),
            'fav_count' => $query->func()->count(
                $query->func()->distinct(['Favs.id' => 'identifier'])
            ),
        ];
    })
    ->autoFields(true)
    ->contain(['Likes', 'Favs'])
    ->leftJoinWith('Likes')
    ->leftJoinWith('Favs')
    ->group(['Users.id']);

Использование построителя функций для генерации DISTINCT является обходным путем, так как пока нет API, который позволил бы специально сгенерировать ключевое слово. Результатом будет что-то вроде DISTINCT(Likes.id), но он будет работать нормально, круглые скобки будут интерпретироваться как часть выражения после ключевого слова, а не как часть вызова функции.

Большое спасибо! Добавление отдельного предложения было ключом к моей проблеме

pepito 14.12.2020 10:34

Другие вопросы по теме