12/08/2018, 16:45

Tìm hiểu về Scout trong Laravel

Laravel Scout cung cấp một giải pháp đơn giản , dựa trên các giải pháp để tìm kiếm full-text cho Eloquent trong models của bạn. Sử dung model quan sát, Scout sẽ tự động giữ những chỉ mục tìm kiếm của bạn đồng bộ với các bản ghi trong Eloquent . Hiện nay, Scout đi kèm với Algolia driver. Tuy ...

Laravel Scout cung cấp một giải pháp đơn giản , dựa trên các giải pháp để tìm kiếm full-text cho Eloquent trong models của bạn. Sử dung model quan sát, Scout sẽ tự động giữ những chỉ mục tìm kiếm của bạn đồng bộ với các bản ghi trong Eloquent .

Hiện nay, Scout đi kèm với Algolia driver. Tuy nhiên, viết các drivers đơn giản và bạn có thể mở rộng Scout với các thực hiện tìm kiếm của chính mình.

Đầu tiên , ta sẽ cài đặt Scout thông qua Composer :

composer require laravel/scout

Sau đó sẽ cài đặt Scout, bạn nên publish cài đặt Scout sử dụng vendor:publish bằng Aritsan command. Lệnh này sẽ tạo cài đặt trong file scout.php trong thư mục config của bạn.

php artisan vendor:publish --provider="LaravelScoutScoutServiceProvider"

Cuối cùng , ta sẽ thêm LaravelScoutSearchable vào model mà bạn muốn searchable. Thiết lập này sẽ đăng kí model để đồng bộ với trình tìm kiếm của bạn.

<?php

namespace App;

use LaravelScoutSearchable;
use IlluminateDatabaseEloquentModel;

class Post extends Model
{
    use Searchable;
}

Mặc dù không bắt buộc phải sử dụng Scout, bạn nên xem xét cấu hình trình điều khiển queue trước khi sử dụng thư viện. Làm việc với queue sẽ cho phép Scout xếp hàng tất cả các hoạt động đồng bộ hóa thông tin mô hình của bạn với các chỉ mục tìm kiếm của bạn, cung cấp thời gian phản hồi tốt hơn cho giao diện web của ứng dụng.

Khi bạn đã configured queue, thiết lập giá trị của queue trong config/scout.php là true

'queue' => true,

Algolia

Khi sử dung Algolia driver, bạn nên configure id và secret của bạn trong file configuration config/scout.php. Khi các thông tin xác thực của bạn đã được định cấu hình, bạn cũng cần phải cài đặt Algolve PHP SDK thông qua Composer:

composer require algolia/algoliasearch-client-php

Configuring Model Indexes

Mỗi một model Eloquent sẽ đồng bộ với một chỉ mục tìm kiếm index, chứa tất cả các bản ghi có thể tìm kiếm cho mô hình đó. Nói cách khác , bạn có thể nghĩ tới mỗi index như một bảng MySQL. Theo mặc định, mỗi mọt model sẽ được duy trì đến index phù hợp với tên table của model.Thông thường , đây chính là hình thức số nhiều của tên model. Tuy nhiên bạn được tự do tùy chỉnh index của model bằng cách overriding phương thức searchableAs trên model:

<?php

namespace App;

use LaravelScoutSearchable;
use IlluminateDatabaseEloquentModel;

class Post extends Model
{
    use Searchable;

    /**
     * Get the index name for the model.
     *
     * @return string
     */
    public function searchableAs()
    {
        return 'posts_index';
    }
}

Configuring Searchable Data Theo mặc định, toàn bộ toArray của một model sẽ được tiếp tục tìm kiếm theo index. Nếu bạn muốn tùy chỉnh data được đồng bộ hóa với chỉ mục tìm kiếm của nó. Nếu bạn muốn tùy chỉnh data được đồng bộ hóa với chỉ mục tìm kiếm , bạn có thể override phương thức toSearchableArray trong model:

<?php

namespace App;

use LaravelScoutSearchable;
use IlluminateDatabaseEloquentModel;

class Post extends Model
{
    use Searchable;

    /**
     * Get the indexable data array for the model.
     *
     * @return array
     */
    public function toSearchableArray()
    {
        $array = $this->toArray();

        // Customize array...

        return $array;
    }
}

Batch Import

Nếu bạn cài đặt Scout vào một project đang tồn tại, bạn có thể dùng bản ghi trong database bạn cần để import cho trình tìm kiếm của bạn. Scout cung cấp lênh artisan thủ cộng để bạn có thể sự dụng để import toàn bộ bản ghi hiện có của bạn vào chỉ mục tìm kiếm index .

php artisan scout:import "AppPost"

Adding Records

Khi bạn đã thêm Laravel Scout Searchable vào trong model, tất cả những gì bạn cần làm là save model và nó sẽ tự động được thêm vào chỉ mục tìm kiếm của bạn. Nếu bạn đã configured Scout để sử dụng queue, công việc hàng đợi của bạn sẽ được thực hiện ở chế độ background:

$order = new AppOrder;

// ...

$order->save();

Adding Via Query

Nếu bạn muốn thêm collection of models vào chỉ mục tìm kiếm của mình thông qua một query, bạn có thể liên kết phương thức tìm kiếm vào trong elequent query. Phương pháp có thể tìm kiếm sẽ kết quả của truy vấn và thêm các bản ghi vào chỉ mục tìm kiếm của bạn. Một lần nữa, nếu bạn đã cấu hình Scout để sử dụng queue, tất cả các khối sẽ được thêm vào trong background các sẽ làm việc trong queue:

// Adding via Eloquent query...
AppOrder::where('price', '>', 100)->searchable();

// You may also add records via relationships...
$user->orders()->searchable();

// You may also add records via collections...
$orders->searchable();

Phương thức searchable có thể được coi là một hoạt động "upsert". Nói cách khác, nếu bản ghi mô hình đã có trong chỉ mục của bạn, nó sẽ được cập nhật. Nếu nó không tồn tại trong chỉ mục tìm kiếm, nó sẽ được thêm vào chỉ mục.

Updating Records Để update searchable model, bạn chỉ cần update các thuộc tính trong model và save ở model cho database của bạn. Scout sẽ tự động thay đổi chỉ mục tìm kiếm :

$order = AppOrder::find(1);

// Update the order...

$order->save();

Bạn cũng có thể sử dụng phương thức searchable trong một truy vấn để update collection của models. Nếu models không tồn tại trong chỉ mục tìm kiếm , chúng ta sẽ tạo ra nó :

// Updating via Eloquent query...
AppOrder::where('price', '>', 100)->searchable();

// You may also update via relationships...
$user->orders()->searchable();

// You may also update via collections...
$orders->searchable();

Removing Records Để xóa một bản ghi trong index, đơn giản là delete ở model từ database. Hình thức loại bỏ này thậm chí tương thích với soft deleted models

$order = AppOrder::find(1);

$order->delete();

Nếu bạn muốn retrieve model trước khi xóa bản ghi, bạn có thể dùng phương thức unsearchable trong eloquent thay thế cho collection

// Removing via Eloquent query...
AppOrder::where('price', '>', 100)->unsearchable();

// You may also remove via relationships...
$user->orders()->unsearchable();

// You may also remove via collections...
$orders->unsearchable();

Pausing Indexing

Đôi khi bạn có thể cần phải thực hiện hàng loạt các hoạt động Eloquent operations trên model mà không đồng bộ hóa dữ liệu mô hình với chỉ mục tìm kiếm của bạn. Bạn có thể thực hiện việc này bằng phương pháp withoutSyncingToSearch. Phương thức này chấp nhận một callback đơn sẽ được thực thi ngay lập tức. Bất kỳ hoạt động mô hình xảy ra trong cuộc gọi lại sẽ không được đồng bộ hóa với chỉ số của mô hình:

AppOrder::withoutSyncingToSearch(function () {
    // Perform model actions...
});

Bạn có thể bắt đầu tìm kiếm trong model sử dụng phương thức search . Phương thức search chấp nhận một chuỗi duy nhất sẽ được sử dụng để tìm kiếm mô hình của bạn. Sau đó, bạn nên nối tiếp phương thức nhận vào truy vấn tìm kiếm để truy xuất các mô hình Tham vọng khớp với truy vấn tìm kiếm đã cho:

$orders = AppOrder::search('Star Trek')->get();

Vì các tìm kiếm Scout trả về một collection of Eloquent models, bạn thậm chí có thể trả lại kết quả trực tiếp từ route hoặc controller và chúng sẽ tự động được chuyển đổi sang JSON:

use IlluminateHttpRequest;

Route::get('/search', function (Request $request) {
    return AppOrder::search($request->search)->get();
});

Nếu bạn muốn lấy một raw kết quả trả về trước khi chuyển chúng sang Eloquent models, bạn nên sử dụng phương thức raw:

$orders = AppOrder::search('Star Trek')->raw();

Các truy vấn tìm kiếm thường sẽ được thực hiện trên chỉ mục được xác định bởi phương pháp có thể tìm kiếm được của model. Tuy nhiên, bạn có thể sử dụng phương thức bên trong để chỉ định một chỉ mục tùy chỉnh cần được tìm kiếm để thay thế:

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

Where Clauses

Scout cho phép bạn thêm các mệnh đề "where" đơn giản vào truy vấn tìm kiếm của bạn. Hiện tại, các khoản này chỉ hỗ trợ kiểm tra bình đẳng số cơ bản và chủ yếu hữu ích cho việc tìm kiếm các truy vấn theo ID . Vì một chỉ mục tìm kiếm không phải là cơ sở dữ liệu quan hệ nên các mệnh đề "where" hiện không được hỗ trợ:

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

Pagination

Ngoài việc lấy ra collection of models, bạn có thể phân trang trang các kết quả tìm kiếm bằng cách sử dụng phương pháp paginate. Phương pháp này sẽ trả về một trường hợp paginator giống như nếu bạn đã paginated một truy vấn thông thường Eloquent:

$orders = AppOrder::search('Star Trek')->paginate();

Bạn có thể chỉ định số lượng các mô hình để lấy ra trên mỗi trang bằng cách chuyển đối số như là đối số đầu tiên cho phương thức phân trang:

$orders = AppOrder::search('Star Trek')->paginate(15);

Once you have retrieved the results, you may display the results and render the page links using Blade just as if you had paginated a traditional Eloquent query:

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

{{ $orders->links() }}

Nếu một trong những công cụ tìm kiếm Scout được xây dựng không phù hợp với nhu cầu của bạn, bạn có thể viết công cụ tùy chỉnh của riêng bạn và đăng ký nó với Scout. Động cơ của bạn nên mở rộng lớp trừu tượng Laravel Scout Engines Engine. Lớp abstract có bảy phương pháp mà công cụ tùy chỉnh của bạn phải thực hiện:

use LaravelScoutBuilder;

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);

Bạn có thể thấy hữu ích khi xem xét việc triển khai các methods này trên lớp Laravel Scout Engines AlgoliaEngine. Class này sẽ cung cấp cho bạn một điểm khởi đầu tốt để học cách thực hiện từng phương pháp trong công cụ của riêng bạn.

Registering The Engine

Một khi bạn đã viết động cơ tuỳ chỉnh của mình, bạn có thể đăng ký nó với Scout bằng cách sử dụng phương pháp mở rộng của trình quản lý công cụ Scout. Bạn nên gọi phương thức extend từ phương pháp khởi động của AppServiceProvider hoặc bất kỳ nhà cung cấp dịch vụ khác mà ứng dụng của bạn sử dụng. Ví dụ, nếu bạn đã viết một MySqlSearchEngine, bạn có thể đăng ký nó như sau:

use LaravelScoutEngineManager;

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    resolve(EngineManager::class)->extend('mysql', function () {
        return new MySqlSearchEngine;
    });
}

Khi động cơ của bạn đã được đăng ký, bạn có thể chỉ định nó làm trình điều khiển .Scout mặc định trong tệp tin cấu hình config / scout.php của bạn:

'driver' => 'mysql',
0