国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Scout 全文搜索

Scout 全文搜索


Laravel Scout

簡介

Laravel Scout 為 Eloquent 模型 的全文搜索提供了基于驅(qū)動的簡單的解決方案。通過使用模型觀察者, Scout 會自動同步 Eloquent 記錄的搜索索引。

目前, Scout 自帶一個 Algolia 驅(qū)動。不過,編寫自定義驅(qū)動也很簡單,你可以輕松的通過自己的搜索實現(xiàn)來擴展 Scout。

安裝

首先,通過 Composer 包管理器來安裝 Scout:

composer require laravel/scout

Scout 安裝完成后,使用  vendor:publish Artisan 命令來生成 Scout 配置文件。這個命令將在你的 config 目錄下生成一個 scout.php 配置文件。

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

最后,在你要做搜索的模型中添加  Laravel\Scout\Searchable trait。這個 trait 會注冊一個模型觀察者來保持模型和所有驅(qū)動的同步:

<?php
    namespace App;
    use Laravel\Scout\Searchable;
    use Illuminate\Database\Eloquent\Model;
    class Post extends Model{
        use Searchable;
      }

隊列

雖然并不強制使用 Scout,但是在使用這個庫之前,強烈建議你配置一個 隊列驅(qū)動,使用它運行一個隊列來處理允許 Scout 將模型信息同步到搜索索引的所有操作,為你的應(yīng)用的 web 接口提供更快的響應(yīng)。

一旦你配置了隊列驅(qū)動程序,你的 config/scout.php 配置文件中 queue 選項的值要設(shè)置為 true:

'queue' => true,

驅(qū)動必要條件

Algolia

使用 Algolia 驅(qū)動時,需要在 config/scout.php 配置文件配置你的 Algolia idsecret 憑證。配置好憑證之后,還需要使用 Composer 包管理器安裝 Algolia PHP SDK:

composer require algolia/algoliasearch-client-php:^2.2

配置

配置模型索引

每個 Eloquent 模型都是通過給定的 「索引」 進行同步,該 「索引」 包含所有可搜索的模型記錄。換句話說,你可以把每一個 「索引」 設(shè)想為一張 MySQL 數(shù)據(jù)表。默認情況下,每個模型都會被持久化到與模型的 「表」 名(通常是模型名稱的復(fù)數(shù)形式)相匹配的索引。你也可以通過重寫模型上的 searchableAs 方法來自定義模型的索引:

<?php
    namespace App;
    use Laravel\Scout\Searchable;
    use Illuminate\Database\Eloquent\Model;
    class Post extends Model{
        use Searchable;    
      /**
     * 獲取索引名稱
     *
     * @return string
     */   
     public function searchableAs()  
       {   
            return 'posts_index';  
       }
    }

配置可搜索數(shù)據(jù)

默認情況下,模型以完整的 toArray 格式持久化到搜索索引。如果要自定義同步到搜索索引的數(shù)據(jù),可以覆蓋模型上的 toSearchableArray 方法:

<?php
    namespace App;
    use Laravel\Scout\Searchable;
    use Illuminate\Database\Eloquent\Model;
    class Post extends Model{ 
       use Searchable;    
     /**
     * 獲取模型的可搜索數(shù)據(jù)
     *
     * @return array
     */ 
      public function toSearchableArray() 
        {      
          $array = $this->toArray();       
           // Customize array...       
           return $array;    
          }
       }

配置模型 ID

默認情況下,Scout 將使用模型的主鍵作為搜索索引中存儲的唯一 ID 。 可以通過模型上的 getScoutKey 方法自定義:

<?php
    namespace App;
    use Laravel\Scout\Searchable;
    use Illuminate\Database\Eloquent\Model;
    class User extends Model{
        use Searchable;    
     /**
     *  獲取模型主鍵
     *
     * @return mixed
     */   
     public function getScoutKey()  
       {    
           return $this->email;  
         }
     }

索引

批量導(dǎo)入

如果你想安裝 Scout 到已存在的項目中,你可能已經(jīng)有了想要導(dǎo)入搜索驅(qū)動的數(shù)據(jù)庫記錄。Scout 提供了 Artisan 命令 import 用來導(dǎo)入所有已存在的記錄到搜索索引:

php artisan scout:import "App\Post"

flush 命令可用于從搜索索引中刪除所有模型的記錄:

php artisan scout:flush "App\Post"

添加記錄

當(dāng)你將 Laravel\Scout\Searchable trait 添加到模型中,你需要做的就是 save 一個模型實例,它將自動被添加到搜索索引。如果你已經(jīng)將 Scout 配置為 使用隊列,那這個操作會在后臺由你的隊列工作進程來執(zhí)行:

$order = new App\Order;// ...$order->save();

通過查詢添加

如果你想通過 Eloquent 查詢構(gòu)造器將模型集合添加到搜索索引中,你也可以在 Eloquent 查詢構(gòu)造器上鏈式調(diào)用 searchable 方法。searchable 會把構(gòu)造器的查詢 結(jié)果分塊 并且將記錄添加到你的搜索索引里。同樣的,如果你已經(jīng)配置 Scout 為使用隊列,則所有的數(shù)據(jù)塊將在后臺由你的隊列工作進程添加:

// 通過 Eloquent 查詢構(gòu)造器增加..
App\Order::where('price', '>', 100)->searchable();
// 你也可以通過模型關(guān)系增加記錄...
$user->orders()->searchable();
// 你也可以通過集合增加記錄...
$orders->searchable();

searchable 方法可以被看做是「更新插入」的操作。換句話說,如果模型記錄已經(jīng)在你的索引里了,它就會被更新。如果搜索索引中不存在,則將其添加到索引中。

更新記錄

要更新可搜索的模型,只需要更新模型實例的屬性并將模型 save 到數(shù)據(jù)庫。Scout 會自動將更新同步到你的搜索索引中:

$order = App\Order::find(1);
// 更新訂單...
$order->save();

你也可以在 Eloquent 查詢語句上使用 searchable 方法來更新一個模型的集合。如果這個模型不存在你檢索的索引里,就會被創(chuàng)建:

// 通過 Eloquent 查詢更新...
App\Order::where('price', '>', 100)->searchable();
// 你也可以通過數(shù)據(jù)間的關(guān)聯(lián)進行更新...
$user->orders()->searchable();
// 你也可以通過數(shù)據(jù)集合進行更新...
$orders->searchable();

刪除記錄

使用 delete 從數(shù)據(jù)庫中刪除該模型就可以移除索引里的記錄。這種刪除形式甚至與 軟刪除 的模型兼容:

$order = App\Order::find(1);
$order->delete();

如果你不希望記錄在刪除之前被檢索到,可以在 Eloquent 查詢實例或集合上使用 unsearchable 方法:

// 通過 Eloquent 查詢刪除...
App\Order::where('price', '>', 100)->unsearchable();
//  你可以通過數(shù)據(jù)間的關(guān)系進行刪除...
$user->orders()->unsearchable();
// 你可以通過數(shù)據(jù)集合進行刪除...
$orders->unsearchable();

暫停索引

你可能需要在執(zhí)行一批 Eloquent 操作的時候,不同步模型數(shù)據(jù)到搜索索引。此時你可以使用 withoutSyncingToSearch 方法來執(zhí)行此操作。這個方法接受一個立即執(zhí)行的回調(diào)。該回調(diào)中所有的操作都不會同步到模型的索引:

App\Order::withoutSyncingToSearch(function () { 
   // 執(zhí)行模型操作...
  });

有條件的搜索模型實例

有時候你可能需要在某些條件下模型是可搜索的。例如,假設(shè)你有 App\Post 模型可能兩種狀態(tài)之一:「草稿」和「發(fā)布」。你可能只允許搜索 「發(fā)布」過的帖子。為了實現(xiàn)這一點,你需要在模型中定義一個 shouldBeSearchable 方法:

public function shouldBeSearchable(){
    return $this->isPublished();
   }

只有在通過 save 方法、查詢或關(guān)聯(lián)模型操作時,才應(yīng)使用 shouldBeSearchable 方法。直接使用 searchable 方法將使模型或集合的可搜索結(jié)果覆蓋 shouldBeSearchable 方法的結(jié)果:

// 此處將遵循 "shouldBeSearchable" 結(jié)果...
App\Order::where('price', '>', 100)->searchable();
$user->orders()->searchable();$order->save();
// 此處將覆蓋 "shouldBeSearchable" 結(jié)果...
$orders->searchable();
$order->searchable();

搜索

你可以使用 search 方法來搜索模型。search 方法接受一個用于搜索模型的字符串。你還需要在搜索查詢上鏈式調(diào)用 get 方法,才能用給定的搜索語句查詢與之匹配的 Eloquent 模型:

$orders = App\Order::search('Star Trek')->get();

Scout 搜索返回 Eloquent 模型的集合,因此你可以直接從路由或控制器返回結(jié)果,它們會被自動轉(zhuǎn)換成 JSON 格式:

use Illuminate\Http\Request;
Route::get('/search', function (Request $request) {
    return App\Order::search($request->search)->get();
   });

如果你想在它們返回 Eloquent 模型前得到原結(jié)果,你應(yīng)該使用 raw 方法:

$orders = App\Order::search('Star Trek')->raw();

搜索查詢通常會在模型的 searchableAs 方法指定的索引上執(zhí)行。當(dāng)然,你也可以使用 within 方法指定應(yīng)該搜索的自定義索引:

$orders = App\Order::search('Star Trek') 
   ->within('tv_shows_popularity_desc')    
   ->get();

Where 語句

允許你在搜索查詢中增加簡單的 "where" 語句。目前,這些語句只支持基本的數(shù)值等式檢查,并且主要是用于根據(jù)租戶 ID 進行的范圍搜索查詢。由于搜索索引不是關(guān)系型數(shù)據(jù)庫,因此當(dāng)前不支持更高級的 "where" 語句:

$orders = App\Order::search('Star Trek')->where('user_id', 1)->get();

分頁

除了檢索模型的集合,你也可以使用 paginate 方法對搜索結(jié)果進行分頁。這個方法會返回一個就像 傳統(tǒng)的 Eloquent 查詢分頁 一樣的 Paginator 實例:

$orders = App\Order::search('Star Trek')->paginate();

你可以通過將數(shù)量作為第一個參數(shù)傳遞給 paginate 方法來指定每頁檢索多少個模型:

$orders = App\Order::search('Star Trek')->paginate(15);

獲取到檢索結(jié)果后,就可以使用 Blade 來渲染分頁鏈接和顯示檢索結(jié)果,就像傳統(tǒng)的 Eloquent 查詢分頁一樣:

<div class="container">
    @foreach ($orders as $order) 
           {{ $order->price }}
    @endforeach
    </div>
  {{ $orders->links() }}

軟刪除

如果你的索引模型是 軟刪除 ,并且你需要搜索軟刪除的模型,設(shè)置 config/scout.php 配置文件的 soft_delete 選項的值為 true

'soft_delete' => true,

當(dāng)這個配置選項是 true 的時候, Scout 不會從搜索索引中移除軟刪除模型。相反,它會在索引記錄中設(shè)置一個隱藏 __soft_deleted 屬性。 然后,在搜索的時候,你可以使用 withTrashedonlyTrashed 方法檢索軟刪除記錄:

// 搜索結(jié)果包括已刪除的記錄...
$orders = App\Order::withTrashed()->search('Star Trek')->get();
// 搜索結(jié)果只含已刪除的記錄...
$orders = App\Order::onlyTrashed()->search('Star Trek')->get();

{提示} 要永久刪除模型可以使用 forceDelete 來刪除,Scout 將自動的從搜索索引中移除模型。

自定義搜索引擎

如果需要自定義引擎的搜索行為,可以將回調(diào)作為第二個參數(shù)傳遞給 search 方法。例如,在將搜索查詢傳遞給 Algolia 之前,可以使用這個回調(diào)將地理位置數(shù)據(jù)添加到搜索請求中:

use Algolia\AlgoliaSearch\SearchIndex;
App\Order::search('Star Trek', function (SearchIndex $algolia, string $query, array $options) {
    $options['body']['query']['bool']['filter']['geo_distance'] = [
            'distance' => '1000km',        
            'location' => ['lat' => 36, 'lon' => 111],  
          ];    
     return $algolia->search($query, $options);
  })->get();

自定義引擎

寫引擎

如果內(nèi)置的 Scout 搜索引擎不能滿足你的需求,你可以編寫自定義的引擎并且將它注冊到 Scout。你的引擎需要繼承 Laravel\Scout\Engines\Engine 抽象類,這個抽象類包含了你自定義的引擎必須要實現(xiàn)的七個方法:

use Laravel\Scout\Builder;
abstract public function update($models);
abstract public function delete($models);
abstract public function search(Builder $builder);
abstract public function paginate(Builder $builder, $perPage, $page);
abstract public function mapIds($results);
abstract public function map($results, $model);
abstract public function getTotalCount($results);
abstract public function flush($model);

Laravel\Scout\Engines\AlgoliaEngine 類里查看這些方法的實現(xiàn)會對你有較大的幫助。這個類會為你在學(xué)習(xí)如何在自定義引擎中實現(xiàn)這些方法提供一個好的起點。

注冊引擎

一旦你寫好了自定義引擎,你可以用 Scout 引擎管理的 extend 方法將它注冊到 Scout。你只需要從 AppServiceProvider 下的 boot 方法或者應(yīng)用中使用的任何一個服務(wù)提供器中調(diào)用 extend 方法。舉個例子,如果你寫好了一個 MySqlSearchEngine,你可以像這樣去注冊它:

use Laravel\Scout\EngineManager;
/**
 * 啟動任何的服務(wù)
 *
 * @return void
 */
 public function boot(){ 
    resolve(EngineManager::class)->extend('mysql', function () {
            return new MySqlSearchEngine;   
         });
      }

引擎注冊后,你可以在 config/scout.php 配置文件中指定它為默認的 Scout driver

'driver' => 'mysql',

生成宏命令

如果你想要自定義生成器方法,你可以使用   Laravel\Scout\Builder  類下的 macro  方法。通常,定義 "macros" 時, 需要實現(xiàn) service provider's  boot 方法:

<?php
    namespace App\Providers;
    use Laravel\Scout\Builder;
    use Illuminate\Support\ServiceProvider;
    use Illuminate\Support\Facades\Response;
    class ScoutMacroServiceProvider extends ServiceProvider{  
      /**
     * 注冊應(yīng)用的Scout 宏命令.
     *
     * @return void
     */  
       public function boot()  
         {     
            Builder::macro('count', function () {
                 return $this->engine->getTotalCount(           
                      $this->engine()->search($this)    
                           );     
                     });   
           }
        }

macro  函數(shù)接受一個名字作為第一個參數(shù),第二個參數(shù)為一個閉包函數(shù)。當(dāng)
調(diào)用 Laravel\Scout\Builder  宏命令時,調(diào)用這個函數(shù).

App\Order::search('Star Trek')->count();
本文章首發(fā)在 LearnKu.com 網(wǎng)站上。