之前在自己的 Laravel 6.x 測試專案中使用 Elasticsearch 做全文搜尋,發現 Elasticsearch 在中文搜尋部分有問題,請孤狗大神找了相當多資料,絕大部份中文資料都停留在 Laravel 6.x 以下,試驗了 ICU 及 IK 中文分詞插件也不盡理想,可能是我功力太差,不知道如何設定,只好放棄使用 Elasticsearch 了,改用輕量的 TNTSearch。
前置準備
TNTSearch 不像 Elasticsearch 那樣複雜,只需安裝 Sqlite3 當作資料庫,XAMMP 需修改 php.ini 將 sqlite3 啟用,並下載 Windows 版本的 dll 放到 XAMPP 的 Apache/bin 目錄中,重新啟動 Apache 即可。
# 將註解拿掉
extension=pdo_sqlite
extension=sqlite3
安裝 Laravel Scout 及 vanry/laravel-scout-tntsearch 套件
vanry/laravel-scout-tntsearch 這個套件會自動將 TNTSearch 驅動一併安裝。
composer require vanry/laravel-scout-tntsearch
# Scout 設定檔
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
# Tntsearch 設定檔
php artisan vendor:publish --provider="Vanry\Scout\TNTSearchScoutServiceProvider"
修改 .env 設定
SCOUT_DRIVER=tntsearch
SCOUT_QUEUE=false
TNTSEARCH_FUZZINESS=true
TNTSEARCH_BOOLEAN=true
TNTSEARCH_TOKENIZER=phpanalysis
模型使用 Trait 方法
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;
class Post extends Model
{
use HasFactory;
use Searchable;
public function toSearchableArray()
{
return [
'id' => $this->id,
'title' => $this->title,
'content' => $this->content,
];
}
}
導入資料
# scout 命令
php artisan scout:import 'App\Models\Post'
# tntsearch 命令, 性能更好
php artisan tntsearch:import 'App\Models\Post'
搜尋資料
Post::search('laravel教程')->get();
注意事項
- 中文分詞有三種方式 scws 、jieba 和 phpanalysis,預設使用 phpanalysis。
- 使用 phpanalysis 在搜尋時,英文必須完整的字,例如:word 不能用 wo 來搜尋,中文字必須輸入兩個字以上才會搜尋到資料,不能只單一輸入一個中文字。例如:周杰倫,不能只輸入周字來查詢所有周姓。
目前僅測試 phpanalysis 分詞方式,其餘 scws 及 jieba 尚未測試。