使用 Laravel Scout + ElasticSearch 實現全文搜尋

laradocs發表於2021-10-15

前言

為了對資料庫執行高階搜尋(例如全文搜尋),關係型資料庫提供的功能很有限。這就是為什麼有必要使用合適的搜尋引擎,例如:Lucene、Solr 或Elasticsearch。

快速開始

在開始之前,我們要確保已經安裝了 ElasticSearch 應用程式。

安裝 Scout 驅動程式

  1. 通過 composer 安裝 Scout 包

我們可以執行以下命令安裝:

composer require laravel/scout
  1. 將 ScoutServiceProvider 類新增到 config/app.php 檔案的 providers 列表中(5.4 以上版本可以跳過此步驟):

config/app.php

'providers' => [
    ...
    // Laravel Scout
    Laravel\Scout\ScoutServiceProvider::class,
]
  1. 釋出 Scout 的配置檔案
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"

安裝 ElasticSearch 驅動程式

目前,Laravel 預設使用 AlgoliaMeiliSearch 驅動程式,但是 Laravel 允許我們編寫自定義驅動程式。因此,我們選擇第三方提供的包來擴充套件 Sout 驅動程式。

  1. 通過 composer 安裝 ElasticSearch 包
composer require tamayo/laravel-scout-elastic
  1. 將 ElasticsearchProvider 類新增到 config/app.php 檔案的 providers 列表中(5.4 以上版本可以跳過此步驟)

config/app.php

'providers' => [
    ...
    // Laravel Scout
    Laravel\Scout\ScoutServiceProvider::class,
    // ElasticSearch
    ScoutEngines\Elasticsearch\ElasticsearchProvider::class,
]
  1. 修改 scout.php 配置檔案中的驅動值

config/scout.php

'driver' => env('SCOUT_DRIVER','elasticsearch'),

當然,也可以把 SCOUT_DRIVER 新增到 .env 檔案中。

  1. 將 ElasticSearch 驅動新增到 scout.php 檔案中

config/scout.php

'elasticsearch' => [ 
    'index' => env ('ELASTICSEARCH_INDEX', 'laravel'), 
    'config' => [ 
        'hosts' => [ 
            env ('ELASTICSEARCH_HOST', 'localhost'), 
        ], 
    ], 
] ,
  1. .env 檔案中新增 ElasticSearch 配置

.env

ELASTICSEARCH_INDEX = 偵察
ELASTICSEARCH_HOST = http://localhost:9200

現在,所有的安裝和配置都完成,接下來就是測試 Laravel 和 ElasticSearch 的整合了。

全文搜尋

建立模型

我們可以使用以下命令建立模型:

php artisan make:model Post -a

Post 模型中,我們需要新增 Searchable Trait,如下所示:

<?php

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Laravel\Scout\Searchable;

class Post extends Model
{
    use HasFactory, Searchable;

    protected $fillable = [
        'subject'
    ];
}

在遷移檔案中,我們建立帶有 subject 欄位的 posts 表:

public function up()
{
    Schema::create('refunds', function (Blueprint $table) {
        $table->id();
        $table->string ( 'subject' ); 
        $table->timestamps();
    }

最後,我們執行資料庫遷移命令:

php artisan migrate

Scout 索引

我們需要執行 scout:import 命令在 ElasticSearch 上建立索引,並同步表和和索引之間的資料:

php artisan scout:import "App\Post"

測試搜尋

我們需要使用 faker 資料填充 posts 表,我們使用先前由建立模型命令生成的 PostFactory 工廠:

public function definition()
{
    return [
        'subject' => $this->faker->sentence ( 5 )
    ];
}

我們開啟 Tinker 建立 200 條資料:

php artisan tinker

App\Models\Post::factory ( 200 )->create();

現在我們對單詞 nam 進行搜尋並獲取前兩條資料:

App\Models\Post::search ( 'nam' )->limit(2)->get();

正常情況我們能看見下面類似的結果:

=> Illuminate\Database\Eloquent\Collection {#3732
     all: [
       App\Models\Post {#3726
         id: 34,
         subject: "Ut nam illo quis architecto ut.",
         created_at: "2021-10-15 08:40:14",
         updated_at: "2021-10-15 08:40:14",
       },
       App\Models\Post {#3727
         id: 36,
         subject: "Provident qui nam rerum.",
         created_at: "2021-10-15 08:40:14",
         updated_at: "2021-10-15 08:40:14",
       },
     ],
   }

我們還可以使用過濾器進行全文搜尋,如下所示:

App\Models\Post::search ( 'illo quis' )->where ( 'id', 34 )->get();

同樣,我們可以得到以下結果:

=> Illuminate\Database\Eloquent\Collection {#3732
     all: [
       App\Models\Post {#3726
         id: 34,
         subject: "Ut nam illo quis architecto ut.",
         created_at: "2021-10-15 08:40:14",
         updated_at: "2021-10-15 08:40:14",
       },
     ],
   }
本作品採用《CC 協議》,轉載必須註明作者和本文連結
站在巨人的肩上

相關文章