このパッケージは、SQLデータベースをストレージバックエンドとして使用して、インデックス付きモデルデータでフルテキスト検索を実行する一般的なLaravel Scoutドライバーを提供します。インデックス付きデータは正規化された形式で保存され、完全および/または正確な一致を必要としない効率的でファジーな検索が可能になります。
このドライバーはteamtnt/laravel-scout-tntsearch-driverに代わるものです。主な違いは、このドライバーがより少ない機能(GEO検索など)を提供することです。代わりに、Laravel自体(基本的にすべてのPDOドライバー)によってサポートされているすべてのデータベースシステムで動作します。また、検索アルゴリズムはわずかに異なります。
すべてのテストは、次のデータベースシステムでPHP 8.0、8.1および8.2のGitHubアクションを使用して実行されます。
サポートされているデータベースシステムに関する実際の制限は、主にStaudenmeir/Laravel-Cteを使用した一般的なテーブル式の使用に関連しています。パッケージを使用する前に、データベースシステムがサポートされていることを確認してください。または、データベースエラーが発生する場合があります。
Composer経由でパッケージをインストールできます。
composer require namoshek/laravel-scout-databaseパッケージをインストールした後、構成ファイルと移行を公開する必要があります。
php artisan vendor:publish --provider= " NamoshekScoutDatabaseScoutDatabaseServiceProvider " --tag= " config "
php artisan vendor:publish --provider= " NamoshekScoutDatabaseScoutDatabaseServiceProvider " --tag= " migrations "このパッケージによって作成されたテーブルにscout_とは異なるテーブルプレフィックスを使用する場合は、それに応じて構成とコピーの移行を変更する必要があります。そうした場合、データベースの移行を適用できます。
php artisan migratev0.xからv1.xにアップグレードします新しいバージョンでは、データベーススキーマが変更され、以下を使用して新しい移行を公開する必要があります。
php artisan vendor:publish --provider= " NamoshekScoutDatabaseScoutDatabaseServiceProvider " --tag= " migrations "インストールセクションの上記と同じヒントも、新しく公開された移行にも適用されます。
構成はわずかに削減されており、新しい構成ファイルを古いファイルと比較して、時代遅れの設定を削除することをお勧めします。ただし、このパートをスキップすると、スカウトドライバーのパフォーマンスにマイナスの影響はありません。
NamoshekScoutDatabaseCommandsCleanWordsTable::classコマンドが削除されているため、以前に追加した場合は、スケジュールを解除する必要があります。
protectedフィールドと方法のほとんどの発生は、将来の後方互換性の破壊の変化に関する開発を簡素化するために、 privateに変更されました。実装の一部を積極的にオーバーライドしていない場合、これはまったく影響しません。
Scoutにこのパッケージが提供するドライバーを使用するように指示するには、 config/scout.phpのdriverオプションをdatabaseに変更する必要があります。 Scout Configurationファイルを変更しなかった場合は、代わりにSCOUT_DRIVER環境変数をdatabaseに設定することもできます。
パッケージ自体の利用可能なすべての構成オプションはconfig/scout-database.phpにあります。オプションは、ファイル自体で徹底的に説明されています。デフォルトでは、パッケージでは、英語に適したUnicodeTokenizerとPorterStemmerを使用します。検索では、最後のトークンに後続のワイルドカードを追加し、結果にドキュメントを表示するためにすべての検索用語を見つける必要はありません(ただし、少なくとも1つの一致が必要です)。
また、構成ファイルaltoughでwildcard_all_tokens有効にすることにより、各検索トークンにワイルドカードを追加することもできます。
基本的なインストールでは、これらの設定を変更する必要はほとんどありません。ただし、 connectionオプションを確認する必要があります。これを変更する場合は、移行を実行する前にそうしてください。または、間違ったデータベース接続を使用してテーブルが作成されます。
現在、 UnicodeTokenizerのみが利用可能です。文字ではなく、 p{L}およびp{N}の正規性パターンに応じた数字でもない文字で文字列を分割します。これは、ドット、コロン、ダッシュ、空白などが分割基準であることを意味します。
トークン剤の要件が異なる場合は、構成を介して独自の実装を提供できます。 Tokenizerインターフェイスを実装していることを確認してください。
現在、 wamania/php-stemmerパッケージによって実装されたすべてのステマーが利用可能です。ラッパークラスがそれぞれに追加されました。
DanishStemmerDutchStemmerEnglishStemmerFrenchStemmerGermanStemmerItalianStemmerNorwegianStemmerNullStemmer (ステムの無効化に使用できます)PorterStemmer (デフォルト、 EnglishStemmerと同じ)PortugueseStemmerRomanianStemmerRussianStemmerSpanishStemmerSwedishStemmer STEMMERの要件が異なる場合は、構成を介して独自の実装を提供できます。 Stemmerインターフェイスを実装することを確認してください。
パッケージは、公式のスカウト文書に記載されている利用可能なユースケースに従います。ただし、リストされている制限に注意してください。
検索ドライバーは、内部的に単一のテーブルを使用します。単一のテーブルには、用語と協会が文書に含まれています。ドキュメントをインデックス作成する場合(つまり、検索インデックスにモデルを追加または更新します)、エンジンは構成されたトークンザーを使用して各列の入力をトークンに分割します。デフォルトで構成されたトークン剤は、単コード文字または数字で構成される単語に入力,分割するだけです. 、 - 、 _ ! 、 ? 、 / 、白人および他のすべての特殊文字は、トークンのセパレーターと見なされ、トークン剤によって削除されます。このようにして、そのようなキャラクターは検索インデックス自体に決して終わることはありません。
入力がトークン化された後、各トークン(およびこの時点で、実際にトークンが単語になることを期待しています)は、構成されたステムマーを介して実行され、ステム(つまりルートワード)を取得します。このアクションを実行すると、後で同様の単語を検索できます。たとえば、 PorterStemmer 、入力としてのintelligentとintelligenceの両方の出力としてintelligを生成します。これがどのように役立つかは、すぐに検索するときに明確になります。
最後に、このプロセスの結果はデータベースに保存されます。インデックステーブルには、ステム化プロセスの結果とインデックス付きモデル(モデルタイプと識別子)への関連付けが記載されています。その上、インデックス内の各行について、データベースにはドキュメント内の発生数も含まれています。この情報を使用して、エンジンの検索部分内でスコアリングします。
検索クエリを実行すると、インデックス作成に使用されるのと同じトークン化とステミングプロセスが検索クエリ文字列に適用されます。このプロセスの結果は、実際の検索を実行するために使用されるステム(またはルートワード)のリストです。パッケージの構成に応じて、検索は少なくとも1つまたはすべてのステムを含むドキュメントを返します。これは、逆のドキュメント頻度(つまり、検索された単語のいずれかを含むインデックス付きドキュメントとドキュメントの比率)、用語頻度(ドキュメント内の検索用語の発生数)、および用語偏差(ワイルドカード検索にのみ関連する)に基づいて、インデックスの各一致のスコアを計算することによって行われます。返されたのは、希望する制限に達するまで、そのスコアによって順序付けられた順序で注文された文書です。
カスタム列で検索インデックステーブル( scout_index )を拡張することができます。インデックス作成中、これらの列にカスタムコンテンツで満たされ、検索中に検索をこれらの列にスコープすることができます(正確な一致)。この機能は、検索インデックスが複数のテナントが使用するマルチテナントアプリケーションを使用する場合に特に役立ちます。
この例では、検索インデックスに必須のtenant_id列を追加します。
return new class extends Migration {
public function up (): void
{
Schema :: table ( ' scout_index ' , function ( Blueprint $ table ) {
$ table -> uuid ( ' tenant_id ' );
});
}
public function down (): void
{
Schema :: table ( ' scout_index ' , function ( Blueprint $ table ) {
$ table -> dropColumn ([ ' tenant_id ' ]);
});
}
};各モデルのインデックス作成中にtenant_idが追加されます。
class User extends Model
{
public function toSearchableArray (): array
{
return [
' id ' => $ this -> id ,
' name ' => $ this -> name ,
' tenant_id ' => new StandaloneField ( $ this -> tenant_id ),
];
}
}tenant_id 、たとえばhttpリクエストから取得できる$tenantIdに基づいて検索中にフィルタリングされます。
User :: search ( ' Max Mustermann ' )
-> where ( ' tenant_id ' , $ tenantId )
-> get ();明らかに、このパッケージは、ElasticSearchのようなプロフェッショナル検索エンジンを(リモートでも)(リモートであっても)質の高い検索エンジンを提供していません。このソリューションは、かなりシンプルな設定ソリューションを必要とする小規模なプロジェクトを対象としています。
また、注目に値する、次のスカウト機能は現在実装されていません。
User::search('Mustermann')->within('users_without_admins')User::search('Musterfrau')->orderBy('age', 'desc')を使用してカスタムオーダーで検索この検索エンジンの問題の1つは、複数のキューワーカーが単一のドキュメントのインデックス作成に同時に動作する場合に問題につながる可能性があることです(データベースがデッドロックします)。この問題を回避するために、トランザクションに使用される試みの数が設定可能です。デフォルトでは、デッドロック(または他のエラー)が発生した場合、各トランザクションは最大3回試行されます。
MITライセンス(MIT)。詳細については、ライセンスファイルをご覧ください。