From 37f86eb21614880555fb8289ed229dbc7393e67d Mon Sep 17 00:00:00 2001 From: Alexis Saettler Date: Sun, 12 May 2024 15:30:49 +0200 Subject: [PATCH 01/13] feat: add typesense connector --- app/Console/Commands/SetupScout.php | 61 ++++++++++---- app/Helpers/ScoutHelper.php | 27 ++++++- app/Models/Contact.php | 11 +-- app/Models/Group.php | 3 +- app/Models/Note.php | 5 +- composer.json | 1 + composer.lock | 73 ++++++++++++++++- config/scout.php | 118 ++++++++++++++++++++++++++-- 8 files changed, 263 insertions(+), 36 deletions(-) diff --git a/app/Console/Commands/SetupScout.php b/app/Console/Commands/SetupScout.php index 297893d8751..02ee2c6a8db 100644 --- a/app/Console/Commands/SetupScout.php +++ b/app/Console/Commands/SetupScout.php @@ -2,6 +2,7 @@ namespace App\Console\Commands; +use App\Helpers\ScoutHelper; use Illuminate\Console\Command; use Illuminate\Console\ConfirmableTrait; use Symfony\Component\Console\Attribute\AsCommand; @@ -49,24 +50,40 @@ public function handle(): void */ protected function scoutConfigure(): void { - if (config('scout.driver') === 'meilisearch' && config('scout.meilisearch.host') !== '') { + if (ScoutHelper::indexed()) { $this->artisan('☐ Updating indexes on Meilisearch', 'scout:sync-index-settings', ['--verbose' => true]); } } /** - * Import models. + * Flush indexes. */ protected function scoutFlush(): void { - if (config('scout.driver') !== null && $this->option('flush')) { - foreach (config('scout.meilisearch.index-settings') as $index => $settings) { - $name = (new $index)->getTable(); - $this->artisan("☐ Flush {$name} index", 'scout:flush', ['model' => $index, '--verbose' => true]); - } + if (! $this->option('flush')) { + return; + } - $this->info('✓ Indexes flushed'); + switch (config('scout.driver')) { + case 'algolia': + break; + case 'meilisearch': + foreach (config('scout.meilisearch.index-settings') as $index => $settings) { + $name = (new $index)->getTable(); + $this->artisan("☐ Flush {$name} index", 'scout:flush', ['model' => $index, '--verbose' => true]); + } + break; + case 'typesense': + foreach (config('scout.typesense.model-settings') as $index => $settings) { + $name = (new $index)->getTable(); + $this->artisan("☐ Flush {$name} index", 'scout:flush', ['model' => $index, '--verbose' => true]); + } + break; + default: + return; } + + $this->info('✓ Indexes flushed'); } /** @@ -74,14 +91,30 @@ protected function scoutFlush(): void */ protected function scoutImport(): void { - if (config('scout.driver') !== null && $this->option('import')) { - foreach (config('scout.meilisearch.index-settings') as $index => $settings) { - $name = (new $index)->getTable(); - $this->artisan("☐ Import {$name}", 'scout:import', ['model' => $index, '--verbose' => true]); - } + if (! $this->option('import')) { + return; + } - $this->info('✓ Indexes imported'); + switch (config('scout.driver')) { + case 'algolia': + break; + case 'meilisearch': + foreach (config('scout.meilisearch.index-settings') as $index => $settings) { + $name = (new $index)->getTable(); + $this->artisan("☐ Import {$name}", 'scout:import', ['model' => $index, '--verbose' => true]); + } + break; + case 'typesense': + foreach (config('scout.typesense.model-settings') as $index => $settings) { + $name = (new $index)->getTable(); + $this->artisan("☐ Import {$name}", 'scout:import', ['model' => $index, '--verbose' => true]); + } + break; + default: + return; } + + $this->info('✓ Indexes imported'); } private function artisan(string $message, string $command, array $options = []) diff --git a/app/Helpers/ScoutHelper.php b/app/Helpers/ScoutHelper.php index f2d94537a7a..402783c9db2 100644 --- a/app/Helpers/ScoutHelper.php +++ b/app/Helpers/ScoutHelper.php @@ -7,17 +7,17 @@ class ScoutHelper /** * When updating a model, this method determines if we should update the search index. * - * @return bool - * * @codeCoverageIgnore */ - public static function activated() + public static function activated(): bool { switch (config('scout.driver')) { case 'algolia': return config('scout.algolia.id') !== ''; case 'meilisearch': - return config('scout.meilisearch.host') !== ''; + return config('scout.meilisearch.key') !== ''; + case 'typesense': + return config('scout.typesense.client-settings.api_key') !== ''; case 'database': case 'collection': return true; @@ -25,4 +25,23 @@ public static function activated() return false; } } + + /** + * Test if the driver requires indexes. + * + * @codeCoverageIgnore + */ + public static function indexed(): bool + { + switch (config('scout.driver')) { + case 'algolia': + return config('scout.algolia.id') !== ''; + case 'meilisearch': + return config('scout.meilisearch.key') !== ''; + case 'typesense': + return config('scout.typesense.client-settings.api_key') !== ''; + default: + return false; + } + } } diff --git a/app/Models/Contact.php b/app/Models/Contact.php index 623015e84ff..1f03c50907d 100644 --- a/app/Models/Contact.php +++ b/app/Models/Contact.php @@ -93,11 +93,12 @@ public function toSearchableArray(): array return [ 'id' => $this->id, 'vault_id' => $this->vault_id, - 'first_name' => $this->first_name, - 'last_name' => $this->last_name, - 'middle_name' => $this->middle_name, - 'nickname' => $this->nickname, - 'maiden_name' => $this->maiden_name, + 'first_name' => $this->first_name ?? '', + 'last_name' => $this->last_name ?? '', + 'middle_name' => $this->middle_name ?? '', + 'nickname' => $this->nickname ?? '', + 'maiden_name' => $this->maiden_name ?? '', + 'updated_at' => $this->updated_at->timestamp, ]; } diff --git a/app/Models/Group.php b/app/Models/Group.php index abebd24f3ea..d29f736de37 100644 --- a/app/Models/Group.php +++ b/app/Models/Group.php @@ -63,7 +63,8 @@ public function toSearchableArray(): array return [ 'id' => $this->id, 'vault_id' => $this->vault_id, - 'name' => $this->name, + 'name' => $this->name ?? '', + 'updated_at' => $this->updated_at->timestamp, ]; } diff --git a/app/Models/Note.php b/app/Models/Note.php index 7f0fb9fe2f7..d4d71e7e44c 100644 --- a/app/Models/Note.php +++ b/app/Models/Note.php @@ -44,8 +44,9 @@ public function toSearchableArray(): array 'id' => $this->id, 'vault_id' => $this->vault_id, 'contact_id' => $this->contact_id, - 'title' => $this->title, - 'body' => $this->body, + 'title' => $this->title ?? '', + 'body' => $this->body ?? '', + 'updated_at' => $this->updated_at->timestamp, ]; } diff --git a/composer.json b/composer.json index 9fb2ff75a19..5608a8eb630 100644 --- a/composer.json +++ b/composer.json @@ -42,6 +42,7 @@ "stevebauman/location": "^7.0", "thecodingmachine/safe": "^2.5", "tightenco/ziggy": "2.1.0", + "typesense/typesense-php": "^4.9", "uploadcare/uploadcare-php": "^4.1" }, "require-dev": { diff --git a/composer.lock b/composer.lock index cfca7650289..ad5b5521a49 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f68048c67692666099fda98e1c1e2d82", + "content-hash": "135cc0f3ccc57551b6cba6afe4997a37", "packages": [ { "name": "asbiin/laravel-sentry-tunnel", @@ -11292,6 +11292,75 @@ }, "time": "2023-12-08T13:03:43+00:00" }, + { + "name": "typesense/typesense-php", + "version": "v4.9.3", + "source": { + "type": "git", + "url": "https://github.com/typesense/typesense-php.git", + "reference": "50fc2089ff4829c8e0e11d8c674e9da085b49998" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/typesense/typesense-php/zipball/50fc2089ff4829c8e0e11d8c674e9da085b49998", + "reference": "50fc2089ff4829c8e0e11d8c674e9da085b49998", + "shasum": "" + }, + "require": { + "ext-json": "*", + "monolog/monolog": "^2.1 || ^3.0 || ^3.3", + "nyholm/psr7": "^1.3", + "php": ">=7.4", + "php-http/client-common": "^1.0 || ^2.3", + "php-http/discovery": "^1.0", + "php-http/httplug": "^1.0 || ^2.2", + "psr/http-client-implementation": "^1.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "require-dev": { + "squizlabs/php_codesniffer": "3.*", + "symfony/http-client": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Typesense\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Typesense", + "email": "contact@typesense.org", + "homepage": "https://typesense.org", + "role": "Developer" + }, + { + "name": "Abdullah Al-Faqeir", + "email": "abdullah@devloops.net", + "homepage": "https://www.devloops.net", + "role": "Developer" + } + ], + "description": "PHP client for Typesense Search Server: https://github.com/typesense/typesense", + "homepage": "https://github.com/typesense/typesense-php", + "support": { + "docs": "https://typesense.org/api", + "issues": "https://github.com/typesense/typesense-php/issues", + "source": "https://github.com/typesense/typesense-php" + }, + "funding": [ + { + "url": "https://github.com/typesense", + "type": "github" + } + ], + "time": "2024-04-29T15:34:34+00:00" + }, { "name": "uploadcare/uploadcare-php", "version": "v4.2.0", @@ -17153,5 +17222,5 @@ "ext-fileinfo": "*" }, "platform-dev": [], - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.2.0" } diff --git a/config/scout.php b/config/scout.php index d2aafd43956..86e79f3f097 100644 --- a/config/scout.php +++ b/config/scout.php @@ -15,7 +15,8 @@ | 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" + | Supported: "algolia", "meilisearch", "typesense", + | "database", "collection", "null" | */ @@ -122,32 +123,133 @@ /* |-------------------------------------------------------------------------- - | MeiliSearch Configuration + | Meilisearch Configuration |-------------------------------------------------------------------------- | - | Here you may configure your MeiliSearch settings. MeiliSearch is an open + | 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. + | the host and key information for your own Meilisearch installation. | - | See: https://docs.meilisearch.com/guides/advanced_guides/configuration.html + | See: https://www.meilisearch.com/docs/learn/configuration/instance_options#all-instance-options | */ 'meilisearch' => [ 'host' => env('MEILISEARCH_HOST', 'http://localhost:7700'), - 'key' => env('MEILISEARCH_KEY', null), + 'key' => env('MEILISEARCH_KEY'), 'index-settings' => [ Contact::class => [ 'filterableAttributes' => ['id', 'vault_id'], 'sortableAttributes' => ['updated_at'], ], + Group::class => [ + 'filterableAttributes' => ['id', 'vault_id'], + 'sortableAttributes' => ['updated_at'], + ], Note::class => [ 'filterableAttributes' => ['id', 'vault_id', 'contact_id'], 'sortableAttributes' => ['updated_at'], ], + ], + ], + + /* + |-------------------------------------------------------------------------- + | Typesense Configuration + |-------------------------------------------------------------------------- + | + | Here you may configure your Typesense settings. Typesense is an open + | source search engine using minimal configuration. Below, you will + | state the host, key, and schema configuration for the instance. + | + */ + + 'typesense' => [ + 'client-settings' => [ + 'api_key' => env('TYPESENSE_API_KEY'), + 'nodes' => [ + [ + 'host' => env('TYPESENSE_HOST', 'localhost'), + 'port' => env('TYPESENSE_PORT', '8108'), + 'path' => env('TYPESENSE_PATH', ''), + 'protocol' => env('TYPESENSE_PROTOCOL', 'http'), + ], + ], + 'nearest_node' => [ + 'host' => env('TYPESENSE_HOST', 'localhost'), + 'port' => env('TYPESENSE_PORT', '8108'), + 'path' => env('TYPESENSE_PATH', ''), + 'protocol' => env('TYPESENSE_PROTOCOL', 'http'), + ], + 'connection_timeout_seconds' => env('TYPESENSE_CONNECTION_TIMEOUT_SECONDS', 2), + 'healthcheck_interval_seconds' => env('TYPESENSE_HEALTHCHECK_INTERVAL_SECONDS', 30), + 'num_retries' => env('TYPESENSE_NUM_RETRIES', 3), + 'retry_interval_seconds' => env('TYPESENSE_RETRY_INTERVAL_SECONDS', 1), + ], + 'model-settings' => [ + Contact::class => [ + 'collection-schema' => [ + 'fields' => [ + [ + 'name' => '.*', + 'type' => 'auto', + ], + [ + 'name' => '__soft_deleted', + 'type' => 'int32', + 'optional' => true, + ], + [ + 'name' => 'updated_at', + 'type' => 'int32', + ], + ], + 'default_sorting_field' => 'updated_at', + ], + 'search-parameters' => [ + 'query_by' => 'first_name,last_name,middle_name,nickname,maiden_name', + ], + ], Group::class => [ - 'filterableAttributes' => ['id', 'vault_id'], - 'sortableAttributes' => ['updated_at'], + 'collection-schema' => [ + 'fields' => [ + [ + 'name' => '.*', + 'type' => 'auto', + ], + [ + 'name' => '__soft_deleted', + 'type' => 'int32', + 'optional' => true, + ], + [ + 'name' => 'updated_at', + 'type' => 'int32', + ], + ], + 'default_sorting_field' => 'updated_at', + ], + 'search-parameters' => [ + 'query_by' => 'name', + ], + ], + Note::class => [ + 'collection-schema' => [ + 'fields' => [ + [ + 'name' => '.*', + 'type' => 'auto', + ], + [ + 'name' => 'updated_at', + 'type' => 'int32', + ], + ], + 'default_sorting_field' => 'updated_at', + ], + 'search-parameters' => [ + 'query_by' => 'title,body', + ], ], ], ], From 0b74319681a0686134113f00c1d6516e2a06b340 Mon Sep 17 00:00:00 2001 From: Alexis Saettler Date: Mon, 13 May 2024 06:59:56 +0200 Subject: [PATCH 02/13] update --- app/Console/Commands/SetupScout.php | 56 +++++++---------------------- app/Helpers/ScoutHelper.php | 28 +++++++++++++++ app/Models/Contact.php | 6 ++-- app/Models/Group.php | 6 ++-- app/Models/Note.php | 10 +++--- 5 files changed, 48 insertions(+), 58 deletions(-) diff --git a/app/Console/Commands/SetupScout.php b/app/Console/Commands/SetupScout.php index 02ee2c6a8db..7e46915089a 100644 --- a/app/Console/Commands/SetupScout.php +++ b/app/Console/Commands/SetupScout.php @@ -60,30 +60,14 @@ protected function scoutConfigure(): void */ protected function scoutFlush(): void { - if (! $this->option('flush')) { - return; - } + if ($this->option('flush')) { + foreach (config('scout.meilisearch.index-settings') as $index => $settings) { + $name = (new $index)->getTable(); + $this->artisan("☐ Flush {$name} index", 'scout:flush', ['model' => $index, '--verbose' => true]); + } - switch (config('scout.driver')) { - case 'algolia': - break; - case 'meilisearch': - foreach (config('scout.meilisearch.index-settings') as $index => $settings) { - $name = (new $index)->getTable(); - $this->artisan("☐ Flush {$name} index", 'scout:flush', ['model' => $index, '--verbose' => true]); - } - break; - case 'typesense': - foreach (config('scout.typesense.model-settings') as $index => $settings) { - $name = (new $index)->getTable(); - $this->artisan("☐ Flush {$name} index", 'scout:flush', ['model' => $index, '--verbose' => true]); - } - break; - default: - return; + $this->info('✓ Indexes flushed'); } - - $this->info('✓ Indexes flushed'); } /** @@ -91,30 +75,14 @@ protected function scoutFlush(): void */ protected function scoutImport(): void { - if (! $this->option('import')) { - return; - } + if ($this->option('import')) { + foreach (config('scout.meilisearch.index-settings') as $index => $settings) { + $name = (new $index)->getTable(); + $this->artisan("☐ Import {$name}", 'scout:import', ['model' => $index, '--verbose' => true]); + } - switch (config('scout.driver')) { - case 'algolia': - break; - case 'meilisearch': - foreach (config('scout.meilisearch.index-settings') as $index => $settings) { - $name = (new $index)->getTable(); - $this->artisan("☐ Import {$name}", 'scout:import', ['model' => $index, '--verbose' => true]); - } - break; - case 'typesense': - foreach (config('scout.typesense.model-settings') as $index => $settings) { - $name = (new $index)->getTable(); - $this->artisan("☐ Import {$name}", 'scout:import', ['model' => $index, '--verbose' => true]); - } - break; - default: - return; + $this->info('✓ Indexes imported'); } - - $this->info('✓ Indexes imported'); } private function artisan(string $message, string $command, array $options = []) diff --git a/app/Helpers/ScoutHelper.php b/app/Helpers/ScoutHelper.php index 402783c9db2..9cf442f98d7 100644 --- a/app/Helpers/ScoutHelper.php +++ b/app/Helpers/ScoutHelper.php @@ -2,6 +2,8 @@ namespace App\Helpers; +use Illuminate\Database\Eloquent\Model; + class ScoutHelper { /** @@ -44,4 +46,30 @@ public static function indexed(): bool return false; } } + + /** + * Get id and basic elements of this model. + * + * @codeCoverageIgnore + */ + public static function id(Model $model): array + { + switch (config('scout.driver')) { + case 'meilisearch': + $id = (int) $model->id; + break; + case 'typesense': + $id = (string) $model->id; + break; + default: + $id = $model->id; + break; + } + + return [ + 'id' => $id, + 'updated_at' => (int) $model->updated_at->timestamp, + 'created_at' => (int) $model->created_at->timestamp, + ]; + } } diff --git a/app/Models/Contact.php b/app/Models/Contact.php index 1f03c50907d..f1f0333bbda 100644 --- a/app/Models/Contact.php +++ b/app/Models/Contact.php @@ -90,16 +90,14 @@ class Contact extends VCardResource #[SearchUsingFullText(['first_name', 'last_name', 'middle_name', 'nickname', 'maiden_name'])] public function toSearchableArray(): array { - return [ - 'id' => $this->id, + return array_merge(ScoutHelper::id($this), [ 'vault_id' => $this->vault_id, 'first_name' => $this->first_name ?? '', 'last_name' => $this->last_name ?? '', 'middle_name' => $this->middle_name ?? '', 'nickname' => $this->nickname ?? '', 'maiden_name' => $this->maiden_name ?? '', - 'updated_at' => $this->updated_at->timestamp, - ]; + ]); } /** diff --git a/app/Models/Group.php b/app/Models/Group.php index d29f736de37..2411958ecc0 100644 --- a/app/Models/Group.php +++ b/app/Models/Group.php @@ -60,12 +60,10 @@ public function uniqueIds() #[SearchUsingFullText(['name'])] public function toSearchableArray(): array { - return [ - 'id' => $this->id, + return array_merge(ScoutHelper::id($this), [ 'vault_id' => $this->vault_id, 'name' => $this->name ?? '', - 'updated_at' => $this->updated_at->timestamp, - ]; + ]); } /** diff --git a/app/Models/Note.php b/app/Models/Note.php index d4d71e7e44c..c70f9937fdb 100644 --- a/app/Models/Note.php +++ b/app/Models/Note.php @@ -40,14 +40,12 @@ class Note extends Model #[SearchUsingFullText(['title', 'body'])] public function toSearchableArray(): array { - return [ - 'id' => $this->id, - 'vault_id' => $this->vault_id, - 'contact_id' => $this->contact_id, + return array_merge(ScoutHelper::id($this), [ + 'vault_id' => (int) $this->vault_id, + 'contact_id' => (int) $this->contact_id, 'title' => $this->title ?? '', 'body' => $this->body ?? '', - 'updated_at' => $this->updated_at->timestamp, - ]; + ]); } /** From 29f506dce7fa792766f5ae09165ce368adfbe33e Mon Sep 17 00:00:00 2001 From: Alexis Saettler Date: Mon, 13 May 2024 07:18:05 +0200 Subject: [PATCH 03/13] update --- app/Console/Commands/SetupScout.php | 8 +++++--- app/Helpers/ScoutHelper.php | 18 ++++++------------ 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/app/Console/Commands/SetupScout.php b/app/Console/Commands/SetupScout.php index 7e46915089a..228086a8b37 100644 --- a/app/Console/Commands/SetupScout.php +++ b/app/Console/Commands/SetupScout.php @@ -51,7 +51,7 @@ public function handle(): void protected function scoutConfigure(): void { if (ScoutHelper::indexed()) { - $this->artisan('☐ Updating indexes on Meilisearch', 'scout:sync-index-settings', ['--verbose' => true]); + $this->artisan('☐ Updating indexes', 'scout:sync-index-settings', ['--verbose' => true]); } } @@ -60,7 +60,8 @@ protected function scoutConfigure(): void */ protected function scoutFlush(): void { - if ($this->option('flush')) { + if ($this->option('flush') && ScoutHelper::indexed()) { + // Using meilisearch config for any driver foreach (config('scout.meilisearch.index-settings') as $index => $settings) { $name = (new $index)->getTable(); $this->artisan("☐ Flush {$name} index", 'scout:flush', ['model' => $index, '--verbose' => true]); @@ -75,7 +76,8 @@ protected function scoutFlush(): void */ protected function scoutImport(): void { - if ($this->option('import')) { + if ($this->option('import') && ScoutHelper::indexed()) { + // Using meilisearch config for any driver foreach (config('scout.meilisearch.index-settings') as $index => $settings) { $name = (new $index)->getTable(); $this->artisan("☐ Import {$name}", 'scout:import', ['model' => $index, '--verbose' => true]); diff --git a/app/Helpers/ScoutHelper.php b/app/Helpers/ScoutHelper.php index 9cf442f98d7..862aa75bcb6 100644 --- a/app/Helpers/ScoutHelper.php +++ b/app/Helpers/ScoutHelper.php @@ -54,22 +54,16 @@ public static function indexed(): bool */ public static function id(Model $model): array { - switch (config('scout.driver')) { - case 'meilisearch': - $id = (int) $model->id; - break; - case 'typesense': - $id = (string) $model->id; - break; - default: - $id = $model->id; - break; + $id = $model->getKey(); + + if ($id !== null && $model->getKeyType() === 'string') { + $id = (string) $id; } return [ 'id' => $id, - 'updated_at' => (int) $model->updated_at->timestamp, - 'created_at' => (int) $model->created_at->timestamp, + 'created_at' => (int) $model->getAttribute(Model::CREATED_AT)->timestamp, + 'updated_at' => (int) $model->getAttribute(Model::UPDATED_AT)->timestamp, ]; } } From 6272f2d340013893bba93cdeaf6759430eb28bd9 Mon Sep 17 00:00:00 2001 From: Alexis Saettler Date: Mon, 13 May 2024 07:31:22 +0200 Subject: [PATCH 04/13] update --- .env.example | 4 +++- app/Models/Contact.php | 4 ++-- app/Models/Group.php | 2 +- app/Models/Note.php | 4 ++-- app/Models/Vault.php | 2 +- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.env.example b/.env.example index 4040b53090e..89ddb4552b7 100644 --- a/.env.example +++ b/.env.example @@ -84,12 +84,14 @@ MAIL_REPLY_TO_NAME="${APP_NAME}" # Search # We use Laravel Scout to do full-text search. # Read config/scout.php for more information. -# Note that you have to use Meilisearch, Algolia or the database driver to enable +# Note that you have to use Meilisearch, Typesense, Algolia or the database driver to enable # search in Monica. Searching requires a queue to be configured. SCOUT_DRIVER=database SCOUT_QUEUE=true MEILISEARCH_HOST= MEILISEARCH_KEY= +TYPESENSE_API_KEY= +TYPESENSE_HOST= # Notification channels TELEGRAM_BOT_TOKEN= diff --git a/app/Models/Contact.php b/app/Models/Contact.php index f1f0333bbda..98c03129afb 100644 --- a/app/Models/Contact.php +++ b/app/Models/Contact.php @@ -91,7 +91,7 @@ class Contact extends VCardResource public function toSearchableArray(): array { return array_merge(ScoutHelper::id($this), [ - 'vault_id' => $this->vault_id, + 'vault_id' => (string) $this->vault_id, 'first_name' => $this->first_name ?? '', 'last_name' => $this->last_name ?? '', 'middle_name' => $this->middle_name ?? '', @@ -119,7 +119,7 @@ public function scopeActive(Builder $query): Builder } /** - * Used to delete related objects from Meilisearch/Algolia instance. + * Used to delete related objects from scout driver instance. */ protected static function boot(): void { diff --git a/app/Models/Group.php b/app/Models/Group.php index 2411958ecc0..176215bbd81 100644 --- a/app/Models/Group.php +++ b/app/Models/Group.php @@ -61,7 +61,7 @@ public function uniqueIds() public function toSearchableArray(): array { return array_merge(ScoutHelper::id($this), [ - 'vault_id' => $this->vault_id, + 'vault_id' => (string) $this->vault_id, 'name' => $this->name ?? '', ]); } diff --git a/app/Models/Note.php b/app/Models/Note.php index c70f9937fdb..1ace2c4a9d9 100644 --- a/app/Models/Note.php +++ b/app/Models/Note.php @@ -41,8 +41,8 @@ class Note extends Model public function toSearchableArray(): array { return array_merge(ScoutHelper::id($this), [ - 'vault_id' => (int) $this->vault_id, - 'contact_id' => (int) $this->contact_id, + 'vault_id' => (string) $this->vault_id, + 'contact_id' => (string) $this->contact_id, 'title' => $this->title ?? '', 'body' => $this->body ?? '', ]); diff --git a/app/Models/Vault.php b/app/Models/Vault.php index f5d4916dd8f..48457acb57e 100644 --- a/app/Models/Vault.php +++ b/app/Models/Vault.php @@ -67,7 +67,7 @@ class Vault extends Model ]; /** - * Used to delete related objects from Meilisearch/Algolia instance. + * Used to delete related objects from scout driver instance. */ protected static function boot(): void { From b860ba373b0803d59e7cb8418cab18c7d69b054b Mon Sep 17 00:00:00 2001 From: Alexis Saettler Date: Mon, 13 May 2024 21:48:33 +0200 Subject: [PATCH 05/13] fix --- app/Helpers/ScoutHelper.php | 9 ++++-- app/Models/Contact.php | 6 +--- app/Models/Group.php | 6 +--- app/Models/Note.php | 6 +--- config/scout.php | 14 ++++++++ ...020_04_25_133132_create_contacts_table.php | 2 +- .../2021_10_09_204235_create_group_table.php | 2 +- .../2021_10_21_013005_create_notes_table.php | 2 +- ...024_05_13_072042_fix_full_text_indexes.php | 32 +++++++++++++++++++ 9 files changed, 59 insertions(+), 20 deletions(-) create mode 100644 database/migrations/2024_05_13_072042_fix_full_text_indexes.php diff --git a/app/Helpers/ScoutHelper.php b/app/Helpers/ScoutHelper.php index 862aa75bcb6..c6fed0ca9f1 100644 --- a/app/Helpers/ScoutHelper.php +++ b/app/Helpers/ScoutHelper.php @@ -54,6 +54,10 @@ public static function indexed(): bool */ public static function id(Model $model): array { + if (config('scout.driver') === 'database') { + return []; + } + $id = $model->getKey(); if ($id !== null && $model->getKeyType() === 'string') { @@ -62,8 +66,9 @@ public static function id(Model $model): array return [ 'id' => $id, - 'created_at' => (int) $model->getAttribute(Model::CREATED_AT)->timestamp, - 'updated_at' => (int) $model->getAttribute(Model::UPDATED_AT)->timestamp, + 'vault_id' => (string) $model->getAttribute('vault_id'), + 'created_at' => (int) optional($model->getAttribute(Model::CREATED_AT))->timestamp, + 'updated_at' => (int) optional($model->getAttribute(Model::UPDATED_AT))->timestamp, ]; } } diff --git a/app/Models/Contact.php b/app/Models/Contact.php index 98c03129afb..5e2c63e87c7 100644 --- a/app/Models/Contact.php +++ b/app/Models/Contact.php @@ -20,7 +20,6 @@ use Illuminate\Support\Arr; use Illuminate\Support\Facades\Auth; use Laravel\Scout\Attributes\SearchUsingFullText; -use Laravel\Scout\Attributes\SearchUsingPrefix; use Laravel\Scout\Searchable; class Contact extends VCardResource @@ -83,15 +82,12 @@ class Contact extends VCardResource /** * Get the indexable data array for the model. * - * * @codeCoverageIgnore */ - #[SearchUsingPrefix(['id', 'vault_id'])] - #[SearchUsingFullText(['first_name', 'last_name', 'middle_name', 'nickname', 'maiden_name'])] + #[SearchUsingFullText(['first_name', 'last_name', 'middle_name', 'nickname', 'maiden_name'], ['expanded' => true])] public function toSearchableArray(): array { return array_merge(ScoutHelper::id($this), [ - 'vault_id' => (string) $this->vault_id, 'first_name' => $this->first_name ?? '', 'last_name' => $this->last_name ?? '', 'middle_name' => $this->middle_name ?? '', diff --git a/app/Models/Group.php b/app/Models/Group.php index 176215bbd81..866bcdb2b4f 100644 --- a/app/Models/Group.php +++ b/app/Models/Group.php @@ -12,7 +12,6 @@ use Illuminate\Database\Eloquent\Relations\MorphOne; use Illuminate\Database\Eloquent\SoftDeletes; use Laravel\Scout\Attributes\SearchUsingFullText; -use Laravel\Scout\Attributes\SearchUsingPrefix; use Laravel\Scout\Searchable; class Group extends VCardResource @@ -53,15 +52,12 @@ public function uniqueIds() /** * Get the indexable data array for the model. * - * * @codeCoverageIgnore */ - #[SearchUsingPrefix(['id', 'vault_id'])] - #[SearchUsingFullText(['name'])] + #[SearchUsingFullText(['name'], ['expanded' => true])] public function toSearchableArray(): array { return array_merge(ScoutHelper::id($this), [ - 'vault_id' => (string) $this->vault_id, 'name' => $this->name ?? '', ]); } diff --git a/app/Models/Note.php b/app/Models/Note.php index 1ace2c4a9d9..ec0bb2655d6 100644 --- a/app/Models/Note.php +++ b/app/Models/Note.php @@ -8,7 +8,6 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\MorphOne; use Laravel\Scout\Attributes\SearchUsingFullText; -use Laravel\Scout\Attributes\SearchUsingPrefix; use Laravel\Scout\Searchable; class Note extends Model @@ -33,15 +32,12 @@ class Note extends Model /** * Get the indexable data array for the model. * - * * @codeCoverageIgnore */ - #[SearchUsingPrefix(['id', 'vault_id'])] - #[SearchUsingFullText(['title', 'body'])] + #[SearchUsingFullText(['title', 'body'], ['expanded' => true])] public function toSearchableArray(): array { return array_merge(ScoutHelper::id($this), [ - 'vault_id' => (string) $this->vault_id, 'contact_id' => (string) $this->contact_id, 'title' => $this->title ?? '', 'body' => $this->body ?? '', diff --git a/config/scout.php b/config/scout.php index 86e79f3f097..4bf6fa642c2 100644 --- a/config/scout.php +++ b/config/scout.php @@ -254,4 +254,18 @@ ], ], + /* + |-------------------------------------------------------------------------- + | Create full text index + |-------------------------------------------------------------------------- + | + | The database driver requires full text indexes on some columns. If you never + | intend to use the database driver, you may want to deactivate those indexes. + | This property is only used during migration of the database. + | Be aware that you won't be able to switch back to the database driver if you + | deactivate the full text indexes. + | + */ + + 'full_text_index' => (bool) env('SCOUT_FULL_TEXT_INDEX', true), ]; diff --git a/database/migrations/2020_04_25_133132_create_contacts_table.php b/database/migrations/2020_04_25_133132_create_contacts_table.php index 97d2e91f630..d511d072110 100644 --- a/database/migrations/2020_04_25_133132_create_contacts_table.php +++ b/database/migrations/2020_04_25_133132_create_contacts_table.php @@ -49,7 +49,7 @@ public function up() $table->index(['vault_id', 'id']); - if (config('scout.driver') === 'database' && in_array(DB::connection()->getDriverName(), ['mysql', 'pgsql'])) { + if (config('scout.full_text_index') && in_array(DB::connection()->getDriverName(), ['mysql', 'pgsql'])) { $table->fullText('first_name'); $table->fullText('last_name'); $table->fullText('middle_name'); diff --git a/database/migrations/2021_10_09_204235_create_group_table.php b/database/migrations/2021_10_09_204235_create_group_table.php index d36a6f656e2..1ac45502ca9 100644 --- a/database/migrations/2021_10_09_204235_create_group_table.php +++ b/database/migrations/2021_10_09_204235_create_group_table.php @@ -53,7 +53,7 @@ public function up() $table->softDeletes(); $table->timestamps(); - if (config('scout.driver') === 'database' && in_array(DB::connection()->getDriverName(), ['mysql', 'pgsql'])) { + if (config('scout.full_text_index') && in_array(DB::connection()->getDriverName(), ['mysql', 'pgsql'])) { $table->fullText('name'); } }); diff --git a/database/migrations/2021_10_21_013005_create_notes_table.php b/database/migrations/2021_10_21_013005_create_notes_table.php index ed54caf6104..891f645033d 100644 --- a/database/migrations/2021_10_21_013005_create_notes_table.php +++ b/database/migrations/2021_10_21_013005_create_notes_table.php @@ -26,7 +26,7 @@ public function up() $table->text('body'); $table->timestamps(); - if (config('scout.driver') === 'database' && in_array(DB::connection()->getDriverName(), ['mysql', 'pgsql'])) { + if (config('scout.full_text_index') && in_array(DB::connection()->getDriverName(), ['mysql', 'pgsql'])) { $table->fullText('title'); $table->fullText('body'); } diff --git a/database/migrations/2024_05_13_072042_fix_full_text_indexes.php b/database/migrations/2024_05_13_072042_fix_full_text_indexes.php new file mode 100644 index 00000000000..f0c435f3e46 --- /dev/null +++ b/database/migrations/2024_05_13_072042_fix_full_text_indexes.php @@ -0,0 +1,32 @@ +addFullTextIndex('contacts', ['first_name', 'last_name', 'middle_name', 'nickname', 'maiden_name']); + $this->addFullTextIndex('groups', ['name']); + $this->addFullTextIndex('notes', ['title', 'body']); + } + + private function addFullTextIndex(string $name, array $columns): void + { + Schema::table($name, function (Blueprint $table) use ($columns) { + if (config('scout.full_text_index') && in_array(DB::connection()->getDriverName(), ['mysql', 'pgsql'])) { + foreach ($columns as $column) { + if (! Schema::hasIndex($table->getTable(), $table->getTable().'_'.$column.'_fulltext')) { + $table->fullText($column); + } + } + } + }); + } +}; From 06d0546bd0dce9efbaac81f599b1c5b934cedb33 Mon Sep 17 00:00:00 2001 From: Alexis Saettler Date: Mon, 13 May 2024 22:54:18 +0200 Subject: [PATCH 06/13] fix --- config/scout.php | 60 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/config/scout.php b/config/scout.php index 4bf6fa642c2..7131bcc4c9d 100644 --- a/config/scout.php +++ b/config/scout.php @@ -191,8 +191,32 @@ 'collection-schema' => [ 'fields' => [ [ - 'name' => '.*', - 'type' => 'auto', + 'name' => 'id', + 'type' => 'string', + ], + [ + 'name' => 'vault_id', + 'type' => 'string', + ], + [ + 'name' => 'first_name', + 'type' => 'string', + ], + [ + 'name' => 'last_name', + 'type' => 'string', + ], + [ + 'name' => 'middle_name', + 'type' => 'string', + ], + [ + 'name' => 'nickname', + 'type' => 'string', + ], + [ + 'name' => 'maiden_name', + 'type' => 'string', ], [ 'name' => '__soft_deleted', @@ -214,8 +238,16 @@ 'collection-schema' => [ 'fields' => [ [ - 'name' => '.*', - 'type' => 'auto', + 'name' => 'id', + 'type' => 'string', + ], + [ + 'name' => 'vault_id', + 'type' => 'string', + ], + [ + 'name' => 'name', + 'type' => 'string', ], [ 'name' => '__soft_deleted', @@ -237,8 +269,24 @@ 'collection-schema' => [ 'fields' => [ [ - 'name' => '.*', - 'type' => 'auto', + 'name' => 'id', + 'type' => 'string', + ], + [ + 'name' => 'vault_id', + 'type' => 'string', + ], + [ + 'name' => 'contact_id', + 'type' => 'string', + ], + [ + 'name' => 'title', + 'type' => 'string', + ], + [ + 'name' => 'body', + 'type' => 'string', ], [ 'name' => 'updated_at', From e73dc90864e1c3efb416994353aab0cb424b166e Mon Sep 17 00:00:00 2001 From: Alexis Saettler Date: Mon, 13 May 2024 23:37:12 +0200 Subject: [PATCH 07/13] update --- app/Helpers/ScoutHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Helpers/ScoutHelper.php b/app/Helpers/ScoutHelper.php index c6fed0ca9f1..2ff190396b8 100644 --- a/app/Helpers/ScoutHelper.php +++ b/app/Helpers/ScoutHelper.php @@ -60,7 +60,7 @@ public static function id(Model $model): array $id = $model->getKey(); - if ($id !== null && $model->getKeyType() === 'string') { + if ($id !== null && $model->getKeyType() === 'string' || config('scout.driver') === 'typesense') { $id = (string) $id; } From bd4360e64d43d49246a5206ee72d61fa19c6124c Mon Sep 17 00:00:00 2001 From: Alexis Saettler Date: Mon, 13 May 2024 23:40:36 +0200 Subject: [PATCH 08/13] update --- .../2024_05_13_072042_fix_full_text_indexes.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/database/migrations/2024_05_13_072042_fix_full_text_indexes.php b/database/migrations/2024_05_13_072042_fix_full_text_indexes.php index f0c435f3e46..8ad527e8ef2 100644 --- a/database/migrations/2024_05_13_072042_fix_full_text_indexes.php +++ b/database/migrations/2024_05_13_072042_fix_full_text_indexes.php @@ -19,14 +19,14 @@ public function up(): void private function addFullTextIndex(string $name, array $columns): void { - Schema::table($name, function (Blueprint $table) use ($columns) { - if (config('scout.full_text_index') && in_array(DB::connection()->getDriverName(), ['mysql', 'pgsql'])) { + if (config('scout.full_text_index') && in_array(DB::connection()->getDriverName(), ['mysql', 'pgsql'])) { + Schema::table($name, function (Blueprint $table) use ($columns) { foreach ($columns as $column) { if (! Schema::hasIndex($table->getTable(), $table->getTable().'_'.$column.'_fulltext')) { $table->fullText($column); } } - } - }); + }); + } } }; From 731949987ab859f7f409100de989e5b5b2bab097 Mon Sep 17 00:00:00 2001 From: Alexis Saettler Date: Mon, 13 May 2024 23:44:35 +0200 Subject: [PATCH 09/13] update example --- .env.example | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.env.example b/.env.example index 89ddb4552b7..93e1e846bdc 100644 --- a/.env.example +++ b/.env.example @@ -82,12 +82,14 @@ MAIL_REPLY_TO_ADDRESS=hello@example.com MAIL_REPLY_TO_NAME="${APP_NAME}" # Search -# We use Laravel Scout to do full-text search. -# Read config/scout.php for more information. -# Note that you have to use Meilisearch, Typesense, Algolia or the database driver to enable -# search in Monica. Searching requires a queue to be configured. +## We use Laravel Scout to do full-text search. +## Read config/scout.php for more information. +## Note that you have to use: 'meilisearch', 'typesense', 'algolia' or the 'database' driver +## to enable search in Monica. Searching requires a queue to be configured. SCOUT_DRIVER=database SCOUT_QUEUE=true +## If you never intend to use the 'database' driver, you can set this value to false: +SCOUT_FULL_TEXT_INDEX=true MEILISEARCH_HOST= MEILISEARCH_KEY= TYPESENSE_API_KEY= From ab8da7a2ac2ddb451ca259b42dfce1c841b56bae Mon Sep 17 00:00:00 2001 From: Alexis Saettler Date: Tue, 14 May 2024 09:26:06 +0200 Subject: [PATCH 10/13] update --- .env.example | 2 +- app/Helpers/ScoutHelper.php | 11 +++++++ config/scout.php | 6 ++-- ...020_04_25_133132_create_contacts_table.php | 4 +-- .../2021_10_09_204235_create_group_table.php | 4 +-- .../2021_10_21_013005_create_notes_table.php | 4 +-- ...024_05_13_072042_fix_full_text_indexes.php | 32 ------------------- 7 files changed, 22 insertions(+), 41 deletions(-) delete mode 100644 database/migrations/2024_05_13_072042_fix_full_text_indexes.php diff --git a/.env.example b/.env.example index 93e1e846bdc..1532d875042 100644 --- a/.env.example +++ b/.env.example @@ -89,7 +89,7 @@ MAIL_REPLY_TO_NAME="${APP_NAME}" SCOUT_DRIVER=database SCOUT_QUEUE=true ## If you never intend to use the 'database' driver, you can set this value to false: -SCOUT_FULL_TEXT_INDEX=true +FULL_TEXT_INDEX=true MEILISEARCH_HOST= MEILISEARCH_KEY= TYPESENSE_API_KEY= diff --git a/app/Helpers/ScoutHelper.php b/app/Helpers/ScoutHelper.php index 2ff190396b8..23ff2a7fc11 100644 --- a/app/Helpers/ScoutHelper.php +++ b/app/Helpers/ScoutHelper.php @@ -3,6 +3,7 @@ namespace App\Helpers; use Illuminate\Database\Eloquent\Model; +use Illuminate\Support\Facades\DB; class ScoutHelper { @@ -47,6 +48,16 @@ public static function indexed(): bool } } + /** + * Test if the driver supports full text indexes. + * + * @codeCoverageIgnore + */ + public static function fullTextIndex(): bool + { + return config('scout.full_text_index') && in_array(DB::connection()->getDriverName(), ['mysql', 'pgsql']); + } + /** * Get id and basic elements of this model. * diff --git a/config/scout.php b/config/scout.php index 7131bcc4c9d..264ae467d8e 100644 --- a/config/scout.php +++ b/config/scout.php @@ -304,7 +304,7 @@ /* |-------------------------------------------------------------------------- - | Create full text index + | Create full text indexes |-------------------------------------------------------------------------- | | The database driver requires full text indexes on some columns. If you never @@ -313,7 +313,9 @@ | Be aware that you won't be able to switch back to the database driver if you | deactivate the full text indexes. | + | Note: Full text indexes are only available on mysql and postgresql databases. + | */ - 'full_text_index' => (bool) env('SCOUT_FULL_TEXT_INDEX', true), + 'full_text_index' => (bool) env('FULL_TEXT_INDEX', true), ]; diff --git a/database/migrations/2020_04_25_133132_create_contacts_table.php b/database/migrations/2020_04_25_133132_create_contacts_table.php index d511d072110..be29eb2256f 100644 --- a/database/migrations/2020_04_25_133132_create_contacts_table.php +++ b/database/migrations/2020_04_25_133132_create_contacts_table.php @@ -1,5 +1,6 @@ index(['vault_id', 'id']); - if (config('scout.full_text_index') && in_array(DB::connection()->getDriverName(), ['mysql', 'pgsql'])) { + if (ScoutHelper::fullTextIndex()) { $table->fullText('first_name'); $table->fullText('last_name'); $table->fullText('middle_name'); diff --git a/database/migrations/2021_10_09_204235_create_group_table.php b/database/migrations/2021_10_09_204235_create_group_table.php index 1ac45502ca9..e331b17df72 100644 --- a/database/migrations/2021_10_09_204235_create_group_table.php +++ b/database/migrations/2021_10_09_204235_create_group_table.php @@ -1,5 +1,6 @@ softDeletes(); $table->timestamps(); - if (config('scout.full_text_index') && in_array(DB::connection()->getDriverName(), ['mysql', 'pgsql'])) { + if (ScoutHelper::fullTextIndex()) { $table->fullText('name'); } }); diff --git a/database/migrations/2021_10_21_013005_create_notes_table.php b/database/migrations/2021_10_21_013005_create_notes_table.php index 891f645033d..787bb24f507 100644 --- a/database/migrations/2021_10_21_013005_create_notes_table.php +++ b/database/migrations/2021_10_21_013005_create_notes_table.php @@ -1,12 +1,12 @@ text('body'); $table->timestamps(); - if (config('scout.full_text_index') && in_array(DB::connection()->getDriverName(), ['mysql', 'pgsql'])) { + if (ScoutHelper::fullTextIndex()) { $table->fullText('title'); $table->fullText('body'); } diff --git a/database/migrations/2024_05_13_072042_fix_full_text_indexes.php b/database/migrations/2024_05_13_072042_fix_full_text_indexes.php deleted file mode 100644 index 8ad527e8ef2..00000000000 --- a/database/migrations/2024_05_13_072042_fix_full_text_indexes.php +++ /dev/null @@ -1,32 +0,0 @@ -addFullTextIndex('contacts', ['first_name', 'last_name', 'middle_name', 'nickname', 'maiden_name']); - $this->addFullTextIndex('groups', ['name']); - $this->addFullTextIndex('notes', ['title', 'body']); - } - - private function addFullTextIndex(string $name, array $columns): void - { - if (config('scout.full_text_index') && in_array(DB::connection()->getDriverName(), ['mysql', 'pgsql'])) { - Schema::table($name, function (Blueprint $table) use ($columns) { - foreach ($columns as $column) { - if (! Schema::hasIndex($table->getTable(), $table->getTable().'_'.$column.'_fulltext')) { - $table->fullText($column); - } - } - }); - } - } -}; From a2dbf623b79a8d0dab5bd9de1e79a3ba8d4faebd Mon Sep 17 00:00:00 2001 From: Alexis Saettler Date: Fri, 15 Nov 2024 00:31:36 +0100 Subject: [PATCH 11/13] fix --- app/Console/Commands/SetupScout.php | 6 +++--- app/Helpers/ScoutHelper.php | 6 +++--- app/Models/Contact.php | 2 +- app/Models/Group.php | 2 +- app/Models/Loan.php | 2 +- app/Models/Note.php | 2 +- .../migrations/2020_04_25_133132_create_contacts_table.php | 2 +- .../migrations/2021_10_09_204235_create_group_table.php | 2 +- .../migrations/2021_10_21_013005_create_notes_table.php | 2 +- 9 files changed, 13 insertions(+), 13 deletions(-) diff --git a/app/Console/Commands/SetupScout.php b/app/Console/Commands/SetupScout.php index 228086a8b37..17086dbb895 100644 --- a/app/Console/Commands/SetupScout.php +++ b/app/Console/Commands/SetupScout.php @@ -50,7 +50,7 @@ public function handle(): void */ protected function scoutConfigure(): void { - if (ScoutHelper::indexed()) { + if (ScoutHelper::isIndexed()) { $this->artisan('☐ Updating indexes', 'scout:sync-index-settings', ['--verbose' => true]); } } @@ -60,7 +60,7 @@ protected function scoutConfigure(): void */ protected function scoutFlush(): void { - if ($this->option('flush') && ScoutHelper::indexed()) { + if ($this->option('flush') && ScoutHelper::isIndexed()) { // Using meilisearch config for any driver foreach (config('scout.meilisearch.index-settings') as $index => $settings) { $name = (new $index)->getTable(); @@ -76,7 +76,7 @@ protected function scoutFlush(): void */ protected function scoutImport(): void { - if ($this->option('import') && ScoutHelper::indexed()) { + if ($this->option('import') && ScoutHelper::isIndexed()) { // Using meilisearch config for any driver foreach (config('scout.meilisearch.index-settings') as $index => $settings) { $name = (new $index)->getTable(); diff --git a/app/Helpers/ScoutHelper.php b/app/Helpers/ScoutHelper.php index 23ff2a7fc11..dda8cc01b6e 100644 --- a/app/Helpers/ScoutHelper.php +++ b/app/Helpers/ScoutHelper.php @@ -12,7 +12,7 @@ class ScoutHelper * * @codeCoverageIgnore */ - public static function activated(): bool + public static function isActivated(): bool { switch (config('scout.driver')) { case 'algolia': @@ -34,7 +34,7 @@ public static function activated(): bool * * @codeCoverageIgnore */ - public static function indexed(): bool + public static function isIndexed(): bool { switch (config('scout.driver')) { case 'algolia': @@ -53,7 +53,7 @@ public static function indexed(): bool * * @codeCoverageIgnore */ - public static function fullTextIndex(): bool + public static function isFullTextIndex(): bool { return config('scout.full_text_index') && in_array(DB::connection()->getDriverName(), ['mysql', 'pgsql']); } diff --git a/app/Models/Contact.php b/app/Models/Contact.php index 5e2c63e87c7..e0069ee2b2d 100644 --- a/app/Models/Contact.php +++ b/app/Models/Contact.php @@ -133,7 +133,7 @@ protected static function boot(): void */ public function searchIndexShouldBeUpdated() { - return ScoutHelper::activated(); + return ScoutHelper::isActivated(); } /** diff --git a/app/Models/Group.php b/app/Models/Group.php index 866bcdb2b4f..ddad00f4014 100644 --- a/app/Models/Group.php +++ b/app/Models/Group.php @@ -69,7 +69,7 @@ public function toSearchableArray(): array */ public function searchIndexShouldBeUpdated() { - return ScoutHelper::activated(); + return ScoutHelper::isActivated(); } /** diff --git a/app/Models/Loan.php b/app/Models/Loan.php index f48d8192cee..543d661baf7 100644 --- a/app/Models/Loan.php +++ b/app/Models/Loan.php @@ -57,7 +57,7 @@ class Loan extends Model */ public function searchIndexShouldBeUpdated() { - return ScoutHelper::activated(); + return ScoutHelper::isActivated(); } /** diff --git a/app/Models/Note.php b/app/Models/Note.php index ec0bb2655d6..14e96ef7c8c 100644 --- a/app/Models/Note.php +++ b/app/Models/Note.php @@ -51,7 +51,7 @@ public function toSearchableArray(): array */ public function searchIndexShouldBeUpdated() { - return ScoutHelper::activated(); + return ScoutHelper::isActivated(); } /** diff --git a/database/migrations/2020_04_25_133132_create_contacts_table.php b/database/migrations/2020_04_25_133132_create_contacts_table.php index a27d9dd184b..b330f6f6bdd 100644 --- a/database/migrations/2020_04_25_133132_create_contacts_table.php +++ b/database/migrations/2020_04_25_133132_create_contacts_table.php @@ -49,7 +49,7 @@ public function up() $table->index(['vault_id', 'id']); - if (ScoutHelper::fullTextIndex()) { + if (ScoutHelper::isFullTextIndex()) { $table->fullText('first_name'); $table->fullText('last_name'); $table->fullText('middle_name'); diff --git a/database/migrations/2021_10_09_204235_create_group_table.php b/database/migrations/2021_10_09_204235_create_group_table.php index a3c34d48511..3d8cce17d5f 100644 --- a/database/migrations/2021_10_09_204235_create_group_table.php +++ b/database/migrations/2021_10_09_204235_create_group_table.php @@ -53,7 +53,7 @@ public function up() $table->softDeletes(); $table->timestamps(); - if (ScoutHelper::fullTextIndex()) { + if (ScoutHelper::isFullTextIndex()) { $table->fullText('name'); } }); diff --git a/database/migrations/2021_10_21_013005_create_notes_table.php b/database/migrations/2021_10_21_013005_create_notes_table.php index df74f114501..3f99f0dc684 100644 --- a/database/migrations/2021_10_21_013005_create_notes_table.php +++ b/database/migrations/2021_10_21_013005_create_notes_table.php @@ -26,7 +26,7 @@ public function up() $table->text('body'); $table->timestamps(); - if (ScoutHelper::fullTextIndex()) { + if (ScoutHelper::isFullTextIndex()) { $table->fullText('title'); $table->fullText('body'); } From a71796adec7497535102a343fb58e434a8a79faa Mon Sep 17 00:00:00 2001 From: Alexis Saettler Date: Fri, 15 Nov 2024 08:44:14 +0100 Subject: [PATCH 12/13] upgrade meilisearch --- composer.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.lock b/composer.lock index 8dbd72c51e1..54bb2b3bf7a 100644 --- a/composer.lock +++ b/composer.lock @@ -3872,16 +3872,16 @@ }, { "name": "meilisearch/meilisearch-php", - "version": "v1.10.1", + "version": "v1.11.0", "source": { "type": "git", "url": "https://github.com/meilisearch/meilisearch-php.git", - "reference": "e3d8a74fdb0c65ecdef6ef9e89c110810c5c1aa0" + "reference": "4dd127cb87848f7a7b28e83bb355b4b86d329867" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/meilisearch/meilisearch-php/zipball/e3d8a74fdb0c65ecdef6ef9e89c110810c5c1aa0", - "reference": "e3d8a74fdb0c65ecdef6ef9e89c110810c5c1aa0", + "url": "https://api.github.com/repos/meilisearch/meilisearch-php/zipball/4dd127cb87848f7a7b28e83bb355b4b86d329867", + "reference": "4dd127cb87848f7a7b28e83bb355b4b86d329867", "shasum": "" }, "require": { @@ -3933,9 +3933,9 @@ ], "support": { "issues": "https://github.com/meilisearch/meilisearch-php/issues", - "source": "https://github.com/meilisearch/meilisearch-php/tree/v1.10.1" + "source": "https://github.com/meilisearch/meilisearch-php/tree/v1.11.0" }, - "time": "2024-09-15T22:50:45+00:00" + "time": "2024-10-28T14:04:37+00:00" }, { "name": "mobiledetect/mobiledetectlib", From 5a4aca70bf10cea249f71ca06e11242a5d0b8614 Mon Sep 17 00:00:00 2001 From: Alexis Saettler Date: Fri, 15 Nov 2024 09:06:37 +0100 Subject: [PATCH 13/13] update doc --- .env.example | 10 ++++++---- .env.example.sail | 2 +- config/scout.php | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.env.example b/.env.example index 1532d875042..8ce8ada5f2b 100644 --- a/.env.example +++ b/.env.example @@ -84,16 +84,18 @@ MAIL_REPLY_TO_NAME="${APP_NAME}" # Search ## We use Laravel Scout to do full-text search. ## Read config/scout.php for more information. -## Note that you have to use: 'meilisearch', 'typesense', 'algolia' or the 'database' driver -## to enable search in Monica. Searching requires a queue to be configured. +## Note that you have to use: 'meilisearch', 'typesense', 'algolia' or the 'database' +## driver to enable search in Monica. Searching requires a queue to be configured. SCOUT_DRIVER=database SCOUT_QUEUE=true ## If you never intend to use the 'database' driver, you can set this value to false: FULL_TEXT_INDEX=true -MEILISEARCH_HOST= +## Meilisearch settings +MEILISEARCH_URL= MEILISEARCH_KEY= -TYPESENSE_API_KEY= +## Typesense settings TYPESENSE_HOST= +TYPESENSE_API_KEY= # Notification channels TELEGRAM_BOT_TOKEN= diff --git a/.env.example.sail b/.env.example.sail index 64f0c82864b..84366d02f05 100644 --- a/.env.example.sail +++ b/.env.example.sail @@ -42,6 +42,6 @@ MAIL_REPLY_TO_NAME="${APP_NAME}" SCOUT_DRIVER=meilisearch SCOUT_QUEUE=true -MEILISEARCH_HOST=http://meilisearch:7700 +MEILISEARCH_URL=http://meilisearch:7700 MEILISEARCH_KEY= MEILISEARCH_NO_ANALYTICS=false diff --git a/config/scout.php b/config/scout.php index 264ae467d8e..0c20c395626 100644 --- a/config/scout.php +++ b/config/scout.php @@ -135,7 +135,7 @@ */ 'meilisearch' => [ - 'host' => env('MEILISEARCH_HOST', 'http://localhost:7700'), + 'host' => env('MEILISEARCH_URL', env('MEILISEARCH_HOST', 'http://localhost:7700')), 'key' => env('MEILISEARCH_KEY'), 'index-settings' => [ Contact::class => [