option('chunk')); $all = (bool) $this->option('all'); $query = PressRelease::query() ->withoutGlobalScope(PortalScope::class) ->withTrashed() ->select(['id', 'title', 'subtitle', 'text', 'keywords']) ->when(! $all, fn (Builder $q) => $q->whereNotExists( fn ($sub) => $sub->select(DB::raw(1)) ->from('press_release_search') ->whereColumn('press_release_search.press_release_id', 'press_releases.id'), )); $total = (clone $query)->toBase()->getCountForPagination(); if ($total === 0) { $this->info('Suchindex ist vollständig — nichts zu tun.'); return self::SUCCESS; } $this->info(($all ? 'Neu indiziert' : 'Ergänzt').": {$total} Pressemitteilungen."); $bar = $this->output->createProgressBar($total); $done = 0; // chunkById statt chunk(): Beim Ergänzen verschwinden die verarbeiteten // Zeilen aus der Ergebnismenge, ein Offset würde dann Einträge // überspringen. $query->chunkById($chunk, function ($releases) use (&$done, $bar): void { $now = now(); PressReleaseSearchIndex::query()->upsert( $releases->map(fn (PressRelease $release): array => [ 'press_release_id' => $release->getKey(), 'title' => (string) $release->title, 'subtitle' => $release->subtitle, 'text' => (string) $release->text, 'keywords' => $release->keywords, 'indexed_at' => $now, ])->all(), ['press_release_id'], ['title', 'subtitle', 'text', 'keywords', 'indexed_at'], ); $done += $releases->count(); $bar->advance($releases->count()); }); $bar->finish(); $this->newLine(2); $this->info("Fertig: {$done} Einträge geschrieben."); return self::SUCCESS; } }