-
Notifications
You must be signed in to change notification settings - Fork 48
fix query issue for dashboar widget #92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,32 +29,27 @@ protected function getData(): array | |
| '#8b5cf6', '#06b6d4', '#ec4899', '#84cc16', | ||
| ]; | ||
|
|
||
| // Generate data for each category over the last 8 weeks | ||
| foreach ($topCategories as $index => $category) { | ||
| $data = Trend::query( | ||
| JobListing::where('job_category', $category->id) | ||
| ) | ||
| ->between( | ||
| start: now()->subWeek(), | ||
| end: now(), | ||
| ) | ||
| ->perWeek() | ||
| ->count(); | ||
|
|
||
| $datasets[] = [ | ||
| 'label' => $category->name, | ||
| 'data' => $data->map(fn (TrendValue $value) => $value->aggregate)->toArray(), | ||
| 'borderColor' => $colors[$index % count($colors)], | ||
| 'backgroundColor' => $colors[$index % count($colors)].'20', | ||
| 'tension' => 0.3, | ||
| ]; | ||
| } | ||
|
|
||
| // Get labels for the last 8 weeks | ||
| $labels = Trend::query(JobListing::class) | ||
| $startDate = now()->subWeek(); | ||
| $endDate = now(); | ||
|
|
||
| // Get all data in a single optimized query to prevent N+1 | ||
| $jobData = JobListing::selectRaw(" | ||
| job_category, | ||
| date_format(created_at, '%Y-%u') as date_week, | ||
| count(*) as count | ||
| ") | ||
| ->whereIn('job_category', $topCategories->pluck('id')) | ||
| ->whereBetween('created_at', [$startDate, $endDate]) | ||
| ->groupBy(['job_category', 'date_week']) | ||
| ->orderBy('date_week') | ||
| ->get() | ||
| ->groupBy('job_category'); | ||
|
|
||
| // Get labels for the date range | ||
| $labels = Trend::query(JobListing::query()) | ||
| ->between( | ||
| start: now()->subWeek(), | ||
| end: now(), | ||
| start: $startDate, | ||
| end: $endDate, | ||
| ) | ||
| ->perWeek() | ||
| ->count() | ||
|
|
@@ -70,6 +65,37 @@ protected function getData(): array | |
| } | ||
| })->toArray(); | ||
|
|
||
| // Generate datasets for each category using the pre-fetched data | ||
| foreach ($topCategories as $index => $category) { | ||
| $categoryData = $jobData->get($category->id, collect()); | ||
|
|
||
| // Create a map of week -> count for this category | ||
| $weekCounts = $categoryData->pluck('count', 'date_week'); | ||
|
|
||
| // Build data array matching the trend format | ||
| $trendData = Trend::query(JobListing::query()) | ||
| ->between( | ||
| start: $startDate, | ||
| end: $endDate, | ||
| ) | ||
| ->perWeek() | ||
| ->count(); | ||
|
|
||
| $data = $trendData->map(function (TrendValue $value) use ($weekCounts) { | ||
| $week = \Carbon\Carbon::parse($value->date)->format('Y-W'); | ||
|
|
||
| return $weekCounts->get($week, 0); | ||
| })->toArray(); | ||
|
|
||
| $datasets[] = [ | ||
| 'label' => $category->name, | ||
| 'data' => $data, | ||
| 'borderColor' => $colors[$index % count($colors)], | ||
| 'backgroundColor' => $colors[$index % count($colors)].'20', | ||
| 'tension' => 0.3, | ||
| ]; | ||
| } | ||
|
|
||
| return [ | ||
| 'datasets' => $datasets, | ||
| 'labels' => $labels, | ||
|
|
@@ -93,25 +119,43 @@ private function getFallbackData(): array | |
| '#8b5cf6', '#06b6d4', '#ec4899', '#84cc16', | ||
| ]; | ||
|
|
||
| // Generate labels for the last 8 weeks | ||
| // Generate labels for the last 2 weeks | ||
| for ($i = 1; $i >= 0; $i--) { | ||
| $startOfWeek = now()->subWeeks($i)->startOfWeek(); | ||
| $labels[] = $startOfWeek->format('M j'); | ||
| } | ||
|
|
||
| // Generate data for each category | ||
| // Get all job data in a single optimized query | ||
| $startDate = now()->subWeeks(1)->startOfWeek(); | ||
| $endDate = now()->endOfWeek(); | ||
|
|
||
| $jobData = JobListing::selectRaw(' | ||
| job_category, | ||
| WEEK(created_at) as week_num, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The WEEK(created_at, 3) as week_num, |
||
| YEAR(created_at) as year_num, | ||
| count(*) as count | ||
| ') | ||
| ->whereIn('job_category', $topCategories->pluck('id')) | ||
| ->whereBetween('created_at', [$startDate, $endDate]) | ||
| ->groupBy(['job_category', 'week_num', 'year_num']) | ||
| ->get() | ||
| ->groupBy('job_category'); | ||
|
|
||
| // Generate data for each category using pre-fetched data | ||
| foreach ($topCategories as $index => $category) { | ||
| $categoryData = $jobData->get($category->id, collect()); | ||
| $data = []; | ||
|
|
||
| for ($i = 1; $i >= 0; $i--) { | ||
| $startOfWeek = now()->subWeeks($i)->startOfWeek(); | ||
| $endOfWeek = now()->subWeeks($i)->endOfWeek(); | ||
| $weekStart = now()->subWeeks($i)->startOfWeek(); | ||
| $weekNum = $weekStart->week; | ||
| $yearNum = $weekStart->year; | ||
|
|
||
| $count = JobListing::where('job_category', $category->id) | ||
| ->whereBetween('created_at', [$startOfWeek, $endOfWeek]) | ||
| ->count(); | ||
| $weekData = $categoryData->where('week_num', $weekNum) | ||
| ->where('year_num', $yearNum) | ||
| ->first(); | ||
|
|
||
| $data[] = $count; | ||
| $data[] = $weekData ? (int) $weekData->count : 0; | ||
| } | ||
|
|
||
| $datasets[] = [ | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
Trendquery inside theforeachloop causes an N+1 query problem, as it's executed for every category. This query should be moved outside the loop to be executed only once, improving performance significantly.