62 lines
1.5 KiB
PHP
62 lines
1.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Jobs\DeleteArtworkFromIndexJob;
|
|
use App\Jobs\IndexArtworkJob;
|
|
use App\Models\Artwork;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
/**
|
|
* Manages Meilisearch index operations for artworks.
|
|
*
|
|
* All write operations are dispatched to queues — never block requests.
|
|
*/
|
|
final class ArtworkSearchIndexer
|
|
{
|
|
/**
|
|
* Queue an artwork for indexing (insert or update).
|
|
*/
|
|
public function index(Artwork $artwork): void
|
|
{
|
|
IndexArtworkJob::dispatch($artwork->id);
|
|
}
|
|
|
|
/**
|
|
* Queue an artwork for re-indexing after an update.
|
|
*/
|
|
public function update(Artwork $artwork): void
|
|
{
|
|
IndexArtworkJob::dispatch($artwork->id);
|
|
}
|
|
|
|
/**
|
|
* Queue removal of an artwork from the index.
|
|
*/
|
|
public function delete(int $id): void
|
|
{
|
|
DeleteArtworkFromIndexJob::dispatch($id);
|
|
}
|
|
|
|
/**
|
|
* Rebuild the entire artworks index in background chunks.
|
|
* Run via: php artisan artworks:search-rebuild
|
|
*/
|
|
public function rebuildAll(int $chunkSize = 500): void
|
|
{
|
|
Artwork::with(['user', 'tags', 'categories', 'stats', 'awardStat'])
|
|
->public()
|
|
->published()
|
|
->orderBy('id')
|
|
->chunk($chunkSize, function ($artworks): void {
|
|
foreach ($artworks as $artwork) {
|
|
IndexArtworkJob::dispatch($artwork->id);
|
|
}
|
|
});
|
|
|
|
Log::info('ArtworkSearchIndexer::rebuildAll — jobs dispatched');
|
|
}
|
|
}
|