WEB/システム/IT技術ブログ

Laravel ScoutとTNTSearchを使用してサイト全文検索を実装してみる

update : 2021/04/18

Google検索を使わずに、自サイトだけで全文検索を実装できないかという事がたまにあります。
Laravelでは全文検索パッケージ「Laravel Scout」が用意されているとの事なので、早速、試してみます。

ここで、Scoutが推奨するのは外部ドライバ「Algolia」なのですが、こちらは有償なので、今回は無償の「TNTSearch」を使用してトライします。
GitHub – teamtnt/tntsearch: A fully featured full text search engine written in PHP
GitHub – teamtnt/laravel-scout-tntsearch-driver: Driver for Laravel Scout search package based on https://github.com/teamtnt/tntsearch

ここで、今回実装した環境は以下の通りです。
Windows 10
PHP 7.4.16
Laravel 6.x

インストールと設定

以下のコマンドを実行して、ScoutとTNTSearchをインストールします。

> composer require laravel/scout
> composer require teamtnt/laravel-scout-tntsearch-driver

すると以下のようなエラーが発生しました。

    - teamtnt/tntsearch v2.7.0 requires ext-sqlite3 * -> it is missing from your system. Install or enable PHP's sqlite3 extension.
    - teamtnt/laravel-scout-tntsearch-driver v11.2.0 requires teamtnt/tntsearch 2.7.0 -> satisfiable by teamtnt/tntsearch[v2.7.0].
    - Root composer.json requires teamtnt/laravel-scout-tntsearch-driver ^11.2 -> satisfiable by teamtnt/laravel-scout-tntsearch-driver[v11.2.0].

拡張モジュール「sqlite3」が必要という事なので、php.iniを開き、以下をコメントアウトを外します。

extension=pdo_sqlite

これでインストールは成功しました。

次に各種設定です。
以下のコマンドを実行して、Scoutの設定ファイルを生成します。

php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"

新規ファイル「…/config/scout.php」が作成されるので、以下の設定を追記します。

	'tntsearch' => [
		'storage'  => storage_path(),
		'fuzziness' => env('TNTSEARCH_FUZZINESS', false),
		'fuzzy' => [
				'prefix_length' => 2,
				'max_expansions' => 50,
				'distance' => 2
		],
		'asYouType' => false,
		'searchBoolean' => env('TNTSEARCH_BOOLEAN', false),
		'maxDocs' => env('TNTSEARCH_MAX_DOCS', 500),
	],

また、ScoutのドライバにTNTSearchを指定します。.envファイルを開き、以下の変数を追記します。

SCOUT_DRIVER=tntsearch

さらに、ファイル「…/config/app.php」を開き、サービスプロバイダを追記します。

	'providers' => [
		...
		Laravel\Scout\ScoutServiceProvider::class,
		TeamTNT\Scout\TNTSearchScoutServiceProvider::class,

インストールと設定は以上です。

検索対象テーブルのインデックスを作成

検索にはインデックスファイルを作成する必要があります。
例えば、全文検索の対象なるテーブルのモデル「…/app/Sample」を編集します。
クラス「Laravel\Scout\Searchable」を追加し、関数「toSearchableArray()」を追加します。

namespace App;

use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;

class Sample extends Model
{
	use Searchable;

	public function toSearchableArray()
	{
			$array = $this->toArray();
			return $array;
	}

以下のコマンドでインデックスファイルを作成します。

> php artisan scout:import App\Sample

「…/storage/samples.index」が作成されたはずです。

検索実行

以上で検索すための準備が整いました。
では、実際に検索を実行してみます。

> php artisan tinker
>>> App\Sample::search('keyword')->get()

keywordに任意の検索ワードを入力すると、検索できていることが確認できると思います。

また、以下のコマンドで、インデックスの状況を確認することができます。

> php artisan scout:status "App\Sample"

実際の検索結果の質についてですが、あまり良くはないです。
例えば「Laravel Scoutで全文検索」での検索結果が1件だった場合、「全文検索」での検索結果が6件、「Scout」での検索結果が0件みたいなことが発生します。
設定などチューニングが正しくない可能性がありますが、期待する結果ではないので、今回は導入を見送ります。
もう少し勉強しないといけないですかね。
やはり全文検索は難しいです。。

B!

Comment

Comment Form

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

Monthly Archives