Laravel: как получить результаты на основе отношения, для которого необходимо подсчитать количество строк

#php #mysql #laravel

#php #mysql #laravel

Вопрос:

извините за заголовок, но лучше объяснить это. Мы создали внутреннее веб-приложение, которое загружает видео, где вы можете комментировать и ставить лайки под видео, как в Instagram. Серверная часть использует Laravel API. Каждый день нам нужно выкрикивать 10 видео, которые получили наибольшее количество лайков со вчерашнего дня, и отношения такие

Видео — имеет много лайков

Нравится — принадлежит видео

 class Stage extends Model
{
  public function likes()
  {
    return $this->hasMany('Applikes', 'id');
  }...

class Likes extends Model
 {
  public function likes()
  {
    return $this->belongsTo('AppVideo', 'videoId');
  }...
  

Я знаю, что мы можем сделать то, что приведено ниже, но извлекает как count, так и VideoID

 DB::table('likes')
->select(DB::raw("
  videoId,
  count(*) as LikeCount"))
->where('createDate', '>=', Carbon::now()->subDay(1)->toDateString())
->where('createDate', '<', Carbon::now()->toDateString())
->groupBy('videoId')
->get();
  

Есть ли способ реализовать это в eloquent, где мне не нужен счетчик, просто нужны идентификаторы видео с наиболее похожим количеством, поскольку я буду использовать идентификаторы для получения сбора видеоинформации. Извините за вопрос новичка, просто интересно, есть ли еще способ сделать это правильно и эффективно, потому что мы ожидаем количество пользователей.

Вот дополнительная информация о таблице

 Schema::create('video', function (Blueprint $table) {
        $table->increments('id')->unsigned();
        $table->integer('userId')->unsigned();
        $table->string('name',255)->nullable();
        $table->text('description')->nullable();
        $table->string('status', 50)->nullable();
        $table->text('video')->nullable();
        $table->dateTime('createDate')->nullable();
        $table->dateTime('upStageDate')->nullable();
        $table->foreign('userId')->references('userId')->on('user')-     >onDelete('cascade');
    });

Schema::create('like', function (Blueprint $table) {
        $table->integer('videoId')->unsigned();
        $table->integer('userId')->unsigned();
        $table->datetime('likeDate')->nullable();
        $table->foreign('userId')->references('userId')->on('user')->onDelete('cascade');
        $table->foreign('videoId')->references('id')->on('video')->onDelete('cascade');
    });
  

Комментарии:

1. Вы пробовали базовую реализацию того же самого с помощью left join? Если нет, пожалуйста, поделитесь структурой таблицы video table, например table. Я понял, что вы также отслеживаете лайки в зависимости от пользователя. Если это так, каждый подобный будет представлен в виде строк. В этом случае вы можете поместить столбец с именем «понравилось» и установить его равным единице при вставке. Таким образом, вы можете взять сумму, а не количество, с помощью left join и groupby . Нужна структура для большего…

2. извините, count также работает одинаково. Sum — это просто еще один метод. Но отношение должно быть правильным в любом случае…

3. @JTheDev обновил вопрос со структурой таблицы

4. Могу ли я узнать, что находится stage или находится videoId в таблице like, напрямую связанной с таблицей video?

5. @JTheDev извините, исправил ссылки на таблицы

Ответ №1:

Есть одна проблема. вы должны указать первичный ключ для таблицы like, по которому мы можем однозначно идентифицировать каждый лайк. Я рассматриваю это как pk_like_id . Затем примените приведенный ниже запрос. Я предполагаю, что VideoID в таблице like — это внешний ключ, ссылающийся на таблицу video. Video:: , который я использовал для указания класса модели video. Сравнение дат вы можете изменить в соответствии с вашей функциональностью. Приведенный ниже запрос найдет только те лайки, которые произошли вчера. Не только для вчерашнего видео. Попробуйте это, это сработало для меня…

 Video::select('video.id', DB::raw('COUNT(like.pk_like_id) as likecount'))
        ->leftJoin('like', 'like.videoId', '=', 'video.id')
        ->where('like.likeDate', '>=', Carbon::now()->subDay(1)->toDateString())
        ->where('like.likeDate', '<', Carbon::now()->toDateString())
        ->groupBy('video.id')
        ->get();
  

Комментарии:

1. @Drew Adorator: Есть какая-нибудь удача …?

2. @DrewAdorador: Рад это слышать… Наслаждайтесь 🙂