*/ public function byService(int $days = 30): array { $since = now()->subDays($days); $recent = PressReleaseCrawlerHit::query() ->where('created_at', '>=', $since) ->selectRaw('service, count(*) as fetches, count(distinct press_release_id) as releases') ->groupBy('service') ->toBase() ->get() ->keyBy('service'); return PressReleaseCrawlerHit::query() ->selectRaw('service, count(*) as fetches_total, max(created_at) as last_at') ->groupBy('service') ->toBase() ->get() ->map(fn (object $row): array => [ 'service' => (string) $row->service, 'label' => CrawlerIdentifier::label((string) $row->service), 'kind' => CrawlerIdentifier::kind((string) $row->service), 'fetches' => (int) ($recent[$row->service]->fetches ?? 0), 'releases' => (int) ($recent[$row->service]->releases ?? 0), 'fetches_total' => (int) $row->fetches_total, 'last_at' => Carbon::parse((string) $row->last_at), ]) ->sortByDesc(fn (array $row): array => [$row['fetches'], $row['fetches_total']]) ->values() ->all(); } /** * Abrufe je Tag über die letzten N Tage, lückenlos, getrennt nach Suche * und KI (Art aus config/crawlers.php). * * @return list */ public function daily(int $days = 14): array { $start = now()->startOfDay()->subDays($days - 1); $counts = PressReleaseCrawlerHit::query() ->where('created_at', '>=', $start) ->selectRaw('date(created_at) as day, service, count(*) as fetches') ->groupBy('day', 'service') ->toBase() ->get() ->groupBy('day'); $series = []; for ($i = 0; $i < $days; $i++) { $day = $start->copy()->addDays($i); $row = ['date' => $day, 'search' => 0, 'ai' => 0]; foreach ($counts->get($day->toDateString(), collect()) as $entry) { $row[CrawlerIdentifier::kind((string) $entry->service) === 'search' ? 'search' : 'ai'] += (int) $entry->fetches; } $series[] = $row; } return $series; } /** * Am häufigsten abgerufene Meldungen im Zeitraum. * * @return list */ public function topReleases(int $days = 30, int $limit = 15): array { return PressReleaseCrawlerHit::query() ->join('press_releases', 'press_releases.id', '=', 'press_release_crawler_hits.press_release_id') ->where('press_release_crawler_hits.created_at', '>=', now()->subDays($days)) ->selectRaw('press_release_crawler_hits.press_release_id, press_releases.title, count(*) as fetches, count(distinct service) as services') ->groupBy('press_release_crawler_hits.press_release_id', 'press_releases.title') ->orderByDesc('fetches') ->limit($limit) ->toBase() ->get() ->map(fn (object $row): array => [ 'press_release_id' => (int) $row->press_release_id, 'title' => (string) $row->title, 'fetches' => (int) $row->fetches, 'services' => (int) $row->services, ]) ->all(); } }