Laravel стремится загружать, чтобы минимизировать запросы

Я использую laravel с DDD Pattern, и вот мой код, чтобы сделать некоторые аналитические отчеты для веб-сайта …

Мой код из репозитория …

//Abstract Entity
public function getFirstBy($key, $value, array $with = array())
{
return $this->repository->getFirstBy($key, $value, $with);
}//Link Entity
$link = parent::getFirstBy('hash', $data['hash'], ['visits']);//prepare report
$report = [];

//get dates difference
$date1 = new \DateTime($data['from']);
$date2 = new \DateTime($data['to']);
$date_diff = $date2->diff($date1)->format("%a");

$time_visits = $link->visits()->whereRaw('DATE(created_at) BETWEEN ? AND ?', array($date1, $date2))->groupBy('created_at')->orderBy('created_at', 'ASC')->get();

//Total Visits
$report['total_visits'] = $time_visits->count();

//country visits
$country_visits = $link->visits()->whereRaw('DATE(created_at) BETWEEN ? AND ?', array($date1, $date2))->orderBy('country_iso', 'ASC')->groupBy('country_iso')->get();

//referrers
$referer_visits = $link->visits()->whereRaw('DATE(created_at) BETWEEN ? AND ?', array($date1, $date2))->where('source', '!=', '')->orderBy('source', 'ASC')->groupBy('source')->get();

//browsers
$browser_visits = $link->visits()->whereRaw('DATE(created_at) BETWEEN ? AND ?', array($date1, $date2))->where('browser', '!=', '')->orderBy('browser', 'ASC')->groupBy('browser')->get();

//os
$os_visits = $link->visits()->whereRaw('DATE(created_at) BETWEEN ? AND ?', array($date1, $date2))->where('os', '!=', '')->orderBy('os', 'ASC')->groupBy('os')->get();The code is working perfectly fine but executing 6 mysql queries which could be a big problem for larger usage...

**sql queries dump...**

select * from `link_visits` where `link_visits`.`link_id` = '4' and DATE(created_at) BETWEEN '2014-09-15 00:00:00' AND '2014-09-17 00:00:00' group by `created_at` order by `created_at` asc

select * from `link_visits` where `link_visits`.`link_id` = '4' and DATE(created_at) BETWEEN '2014-09-15 00:00:00' AND '2014-09-17 00:00:00' group by `country_iso` order by `country_iso` asc

select count(*) as total_visits, medium from `link_visits` where `link_visits`.`link_id` = '4' and DATE(created_at) BETWEEN '2014-09-15 00:00:00' AND '2014-09-17 00:00:00' group by `medium` order by `medium` asc

select * from `link_visits` where `link_visits`.`link_id` = '4' and DATE(created_at) BETWEEN '2014-09-15 00:00:00' AND '2014-09-17 00:00:00' and `source` != '' group by `source` order by `source` asc

select * from `link_visits` where `link_visits`.`link_id` = '4' and DATE(created_at) BETWEEN '2014-09-15 00:00:00' AND '2014-09-17 00:00:00' and `browser` != '' group by `browser` order by `browser` asc

select * from `link_visits` where `link_visits`.`link_id` = '4' and DATE(created_at) BETWEEN '2014-09-15 00:00:00' AND '2014-09-17 00:00:00' and `os` != '' group by `os` order by `os` asc

Please suggest some good ways to optimize it better. thanks, i really need advanced help with this.

0

Решение

Вы можете использовать подзапрос в отношениях для напр.

при условии, что $ link — это ваш объект модели

$link->with(['Visits'=>function($q){
$q->whereRaw('DATE(created_at) BETWEEN ? AND ?', array($date1,$date2))->where('browser', '!=', '')->orderBy('browser', 'ASC')->groupBy('browser');
}])->get();

внутренний запрос отфильтрует все ваши записи соответственно, а внутренний запрос будет применяться только в модели посещений

Я предлагаю сначала получить все записи без каких-либо фильтров, а затем отфильтровать их в объекте коллекции с помощью метода filter ()! так что он будет использовать только 1 запрос на посещение, чтобы получить все записи, тогда вы только переставите их, используя метод filter ()

0

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

Других решений пока нет …

По вопросам рекламы [email protected]