Skip to content

Instantly share code, notes, and snippets.

@mmachatschek
Last active January 22, 2023 00:33
Show Gist options
  • Save mmachatschek/c27ecb45b479d033d68f4355861b10d8 to your computer and use it in GitHub Desktop.
Save mmachatschek/c27ecb45b479d033d68f4355861b10d8 to your computer and use it in GitHub Desktop.
Laravel Scout Sync MeiliSearch Index Settings
<?php
return [
/*
|--------------------------------------------------------------------------
| Default Search Engine
|--------------------------------------------------------------------------
|
| This option controls the default search connection that gets used while
| using Laravel Scout. This connection is used when syncing all models
| to the search service. You should adjust this based on your needs.
|
| Supported: "algolia", "meilisearch", "collection", "null"
|
*/
'driver' => env('SCOUT_DRIVER', 'meilisearch'),
// ....
/*
|--------------------------------------------------------------------------
| Algolia Configuration
|--------------------------------------------------------------------------
|
| Here you may configure your Algolia settings. Algolia is a cloud hosted
| search engine which works great with Scout out of the box. Just plug
| in your application ID and admin API key to get started searching.
|
*/
'algolia' => [
'id' => env('ALGOLIA_APP_ID', ''),
'secret' => env('ALGOLIA_SECRET', ''),
],
/*
|--------------------------------------------------------------------------
| MeiliSearch Configuration
|--------------------------------------------------------------------------
|
| Here you may configure your MeiliSearch settings. MeiliSearch is an open
| source search engine with minimal configuration. Below, you can state
| the host and key information for your own MeiliSearch installation.
|
| See: https://docs.meilisearch.com/guides/advanced_guides/configuration.html
|
*/
'meilisearch' => [
'host' => env('MEILISEARCH_HOST', 'http://meilisearch:7700'),
'key' => env('MEILISEARCH_KEY', null),
/**
* Here is the list of all available settings:
* @see https://docs.meilisearch.com/guides/advanced_guides/settings.html#settings
*
* - updateSearchableAttributes
* - updateDisplayedAttributes
* - updateFilterableAttributes
* - updateSortableAttributes
* - updateRankingRules
* - updateDistinctAttribute
* - updateSynonyms
* - updateStopWords
*/
'settings' => [
YourScoutModel::class => [
'updateSearchableAttributes' => [
'title',
'description',
],
'updateFilterableAttributes' => [
'title',
'__soft_deleted',
]
],
],
],
];
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Laravel\Scout\EngineManager;
use Laravel\Scout\Engines\MeiliSearchEngine;
use MeiliSearch\Client;
use MeiliSearch\Endpoints\Indexes;
class ScoutSync extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'scout:sync {model?}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Sync all scout indexes or a specific model';
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
Log::info('Command: ' . self::class . ' started');
$meilisearchConfigSettings = collect(config('scout.meilisearch.settings'));
if ($meilisearchConfigSettings->count() > 0) {
/** @var MeiliSearchEngine $client */
$client = resolve(EngineManager::class)->driver('meilisearch');
if ($this->argument('model')) {
$modelName = $this->argument('model');
if ($meilisearchConfigSettings->has($modelName)) {
$this->syncModel($client, $modelName, $meilisearchConfigSettings->get($modelName));
} else {
$this->error("No custom settings found for model \"{$modelName}\"");
}
} else {
$this->syncAllModels($client, $meilisearchConfigSettings);
}
} else {
$this->error('No custom settings provided! Nothing to do!');
}
Log::info('Command: ' . self::class . ' finished');
return Command::SUCCESS;
}
/**
* @param Client|MeilisearchEngine $client
* @param string $modelName
* @param array $settings
*/
protected function syncModel($client, string $modelName, array $settings)
{
if (class_exists($modelName)) {
$model = new $modelName();
$index = $client->index($model->searchableAs());
collect($settings)->each(function ($value, $method) use ($index) {
$this->applyMethodOnIndex($index, $method, $value);
});
}
}
/**
* @param Client|MeilisearchEngine $client
* @param Collection $modelSettings
*/
protected function syncAllModels($client, Collection $modelSettings)
{
$modelSettings->each(fn($config, $model) => $this->syncModel($client, $model, $config));
}
protected function applyMethodOnIndex(Indexes $index, $method, $value)
{
$status = $index->{$method}($value);
$message = "Index: \"{$index->getUid()}\" has been updated, "
. "method: \"{$method}\", updateId: {$status['updateId']}";
$this->info($message);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment