From c06219a12091ce4cca10ccc3a2ac4d6a657df862 Mon Sep 17 00:00:00 2001 From: nanaya Date: Wed, 30 Oct 2024 00:02:49 +0900 Subject: [PATCH] Reduce queries for counting notifications --- app/Libraries/NotificationsBundle.php | 30 +++++++++++++++++++-------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/app/Libraries/NotificationsBundle.php b/app/Libraries/NotificationsBundle.php index 512674d2655..0de6edadd6c 100644 --- a/app/Libraries/NotificationsBundle.php +++ b/app/Libraries/NotificationsBundle.php @@ -22,6 +22,7 @@ private static function stackKey(string $objectType, int $objectId, string $cate } private $category; + private array $countByType; private $cursorId; private $objectId; private $objectType; @@ -61,7 +62,7 @@ public function toArray() ]; if ($this->unreadOnly) { - $response['unread_count'] = $this->user->userNotifications()->hasPushDelivery()->where('is_read', false)->count(); + $response['unread_count'] = $this->getTotalNotificationCount(); } return $response; @@ -186,18 +187,29 @@ private function fillTypes(?string $type = null) private function getTotalNotificationCount(?string $type = null) { - $query = Notification::whereHas('userNotifications', function ($q) { - $q->hasPushDelivery()->where('user_id', $this->user->getKey()); - if ($this->unreadOnly) { - $q->where('is_read', false); + if (!isset($this->countByType)) { + $query = Notification ::whereHas('userNotifications', function ($q) { + $q->hasPushDelivery()->where('user_id', $this->user->getKey()); + if ($this->unreadOnly) { + $q->where('is_read', false); + } + }); + + if ($this->objectType !== null) { + $query->where('notifiable_type', $this->objectType); } - }); - if ($type !== null) { - $query->where('notifiable_type', $type); + $this->countByType = $query + ->groupBy('notifiable_type') + ->selectRaw('count(*) type_count, notifiable_type') + ->get() + ->mapWithKeys(fn ($agg) => [$agg->notifiable_type => $agg->type_count]) + ->all(); } - return $query->count(); + return $type === null + ? array_sum($this->countByType) + : $this->countByType[$type] ?? 0; } private function getStackHeads(?string $type = null)