Введение
Hello. В настоящее время я создаю FacebookFeedParser, и на данный момент я пытаюсь создать метод в контроллере, который перечисляет страницы Facebook с наилучшим соотношением post/like от сегодняшнего дня к пользователю. Чтобы сделать это, я построил следующий запрос в чистом SQLОтносительная загрузка, при использовании отбор
SELECT pa.facebook_name, COUNT(po.id) AS postCount, SUM(likes) AS likes, SUM(likes)/COUNT(po.id) AS likesPerPost
FROM facebook_posts po
INNER JOIN facebook_pages pa ON pa.id = po.facebook_page_id
WHERE CONVERT_TZ(`facebook_created_time`, 'UTC', 'Europe/Berlin') > '2015-07-16 00:00:00'
GROUP by facebook_page_id
ORDER BY SUM(likes)/COUNT(po.id) DESC;
Что я теперь хотел сделать, чтобы преобразовать этот запрос в Laravel/красноречив.
Текущее состояние
У меня есть следующие классы в моем проекте
Контроллеры: PageController
, PostController
Модели: FacebookPost
, FacebookPage
, BaseModel
FacebookPost
и FacebookPage
модели оба определяющие их отношение нс нравится эта
FacebookPage
/**
* Defines the relation between FacebookPage and FacebookPost
* One page can have multiple posts
*
* @see FacebookPage
* @see FacebookPost
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function posts()
{
return $this->hasMany(FacebookPost::class);
}
FacebookPost
/**
* Defines the association of this object with FacebookPage
* One facebook_post belongs to one facebook_page
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function page()
{
return $this->belongsTo(FacebookPage::class, 'facebook_page_id');
}
В BaseModel, я определил сферу, которая будет использоваться несколько раз в проекте
/**
* Query scope to get the database values for today
*
* @param $query
* @return mixed
*/
public function scopeToday($query)
{
return $query->whereRaw('CONVERT_TZ(`'. $this->createDateColumn .'`, "UTC", "'. env('APP_TIMEZONE') .'") > "' . Carbon::today()->toDateTimeString() . '"');
}
И это запрос, который я создал для того, чтобы получить эти сообщения. фильтры
$posts = App\Models\FacebookPost::with('page')
->selectRaw('COUNT(id) AS postCount, SUM(likes) AS likes, SUM(likes)/COUNT(id) AS likesPerPost')
->today()
->groupBy('facebook_page_id')
->orderByRaw('SUM(likes)/COUNT(id) DESC')
->get();
Проблема
Проблема у меня в настоящее время имеющий, в том, что, когда я пытаюсь восстановить выше запрос, я не получаю все поля, которые я хочу. Как только я добавлю select
в Builder
, массив relations
с индексом page
имеет значение NULL. Если я опустил метод select
, я получаю FacebookPage, но я хочу иметь эти конкретные поля.
Теперь я получаю объект. Думаю, это потому, что я правильно использую Eloquent Builder
? Не так ли возможно получить только поля, которые я хочу иметь? В результате я ожидаю, должен выглядеть следующим образом (в строке)
facebook_name | postCount | likes | likesPerPost
McDonalds 1000 500 0.5
Я также попробовал, как этот
$posts = App\Models\FacebookPost::with(['page' => function($query) {
$query->select('facebook_name');
}])
->selectRaw('COUNT(id) AS postCount, SUM(likes) AS likes, SUM(likes)/COUNT(id) AS likesPerPost')
->today()
->groupBy('facebook_page_id')
->orderByRaw('SUM(likes)/COUNT(id) DESC')
->get();
мне нужно использовать DB
класс вместо красноречив? Или что было бы лучшим решением для этой проблемы?
Альтернативное решение
$pages = DB::table('facebook_posts')
->select(DB::raw('facebook_pages.facebook_name, COUNT(facebook_posts.id) AS postCount, SUM(likes) AS likes, ROUND(SUM(likes)/COUNT(facebook_posts.id)) AS likesPerPost'))
->join('facebook_pages', 'facebook_posts.facebook_page_id', '=', 'facebook_pages.id')
->whereRaw('CONVERT_TZ(`'. $this->createDateColumn .'`, "UTC", "'. env('APP_TIMEZONE') .'") > "' . Carbon::today()->toDateTimeString() . '"')
->groupBy('facebook_page_id')
->orderByRaw('ROUND(SUM(likes)/COUNT(facebook_posts.id)) DESC')
->get();
Это, однако, работает. Будет ли это правильным решением для моего варианта использования?Я просто спрашиваю, имеет ли смысл использовать Eloquent здесь, поскольку я не пытаюсь получить объект, а данные из нескольких источников.