Scout

Introduzione

Laravel Scout offre una soluzione semplice basata su driver per aggiungere la ricerca full-text ai tuoi modelli Eloquent. Utilizzando gli osservatori dei modelli, Scout manterrà automaticamente i tuoi indici di ricerca sincronizzati con i tuoi record Eloquent.

Attualmente, Scout include i driver Algolia, Meilisearch, Typesense e MySQL / PostgreSQL (database). Inoltre, Scout include un driver "collection" progettato per lo sviluppo locale e non richiede dipendenze esterne o servizi di terze parti. Inoltre, scrivere driver personalizzati è semplice e puoi estendere Scout con le tue implementazioni di ricerca.

Installazione

Per prima cosa, installa Scout tramite il gestore di pacchetti Composer:

composer require laravel/scout

Dopo aver installato Scout, dovresti pubblicare il file di configurazione di Scout usando il comando Artisan vendor:publish. Questo comando pubblicherà il file di configurazione scout.php nella directory config della tua applicazione:

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

Infine, aggiungi il trait Laravel\Scout\Searchable al modello che vuoi rendere ricercabile. Questo trait registrerà un osservatore del modello che terrà automaticamente il modello sincronizzato con il tuo motore di ricerca:

    <?php

    namespace App\Models;

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

    class Post extends Model
    {
        use Searchable;
    }

Queueing

Anche se non è strettamente necessario usare Scout, dovresti considerare fortemente di configurare un queue driver prima di utilizzare la libreria. Eseguire un worker della coda permetterà a Scout di mettere in coda tutte le operazioni che sincronizzano le informazioni del tuo modello con gli indici di ricerca, offrendo tempi di risposta molto migliori per l’interfaccia web della tua applicazione.

Una volta configurato un queue driver, imposta il valore dell’opzione queue nel tuo file di configurazione config/scout.php su true:

    'queue' => true,

Anche quando l’opzione queue è impostata su false, è importante ricordare che alcuni driver di Scout come Algolia e Meilisearch indicizzano sempre i record in modo asincrono. Ciò significa che, anche se l’operazione di indicizzazione è stata completata all’interno della tua applicazione Laravel, il motore di ricerca stesso potrebbe non riflettere immediatamente i nuovi e aggiornati record.

Per specificare la connessione e la coda che i tuoi job Scout utilizzano, puoi definire l’opzione di configurazione queue come un array:

    'queue' => [
        'connection' => 'redis',
        'queue' => 'scout'
    ],

Ovviamente, se personalizzi la connessione e la coda che i job Scout utilizzano, dovresti eseguire un worker della coda per elaborare i job su quella connessione e coda:

    php artisan queue:work redis --queue=scout

Prerequisiti del Driver

Algolia

Quando usi il driver Algolia, devi configurare le credenziali id e secret di Algolia nel file di configurazione config/scout.php. Una volta configurate le credenziali, sarà necessario installare l’SDK PHP di Algolia tramite il gestore di pacchetti Composer:

composer require algolia/algoliasearch-client-php

Meilisearch

Meilisearch è un motore di ricerca open source incredibilmente veloce. Se non sei sicuro di come installare Meilisearch sulla tua macchina locale, puoi utilizzare Laravel Sail, l’ambiente di sviluppo Docker ufficialmente supportato da Laravel.

Quando utilizzi il driver Meilisearch, devi installare l’SDK PHP di Meilisearch tramite il gestore di pacchetti Composer:

composer require meilisearch/meilisearch-php http-interop/http-factory-guzzle

Successivamente, imposta la variabile d’ambiente SCOUT_DRIVER e le credenziali host e key di Meilisearch nel file .env della tua applicazione:

SCOUT_DRIVER=meilisearch
MEILISEARCH_HOST=http://127.0.0.1:7700
MEILISEARCH_KEY=masterKey

Per ulteriori informazioni su Meilisearch, consulta la documentazione di Meilisearch.

Inoltre, assicurati di installare una versione di meilisearch/meilisearch-php compatibile con la versione del tuo binario di Meilisearch consultando la documentazione di Meilisearch riguardo la compatibilità del binario.

Quando aggiorni Scout in un’applicazione che utilizza Meilisearch, dovresti sempre rivedere eventuali cambiamenti incompatibili aggiuntivi al servizio Meilisearch stesso.

Typesense

Typesense è un motore di ricerca open source estremamente veloce e supporta la ricerca per parole chiave, ricerca semantica, ricerca geo e ricerca vettoriale.

Puoi auto-ospitare Typesense oppure utilizzare Typesense Cloud.

Per iniziare a usare Typesense con Scout, installa l’SDK PHP di Typesense tramite il gestore di pacchetti Composer:

composer require typesense/typesense-php

Successivamente, imposta la variabile d’ambiente SCOUT_DRIVER e le credenziali del tuo host Typesense e della chiave API nel file .env della tua applicazione:

SCOUT_DRIVER=typesense
TYPESENSE_API_KEY=masterKey
TYPESENSE_HOST=localhost

Se stai usando Laravel Sail, potresti dover modificare la variabile d’ambiente TYPESENSE_HOST per corrispondere al nome del container Docker. Puoi anche specificare opzionalmente la porta, il percorso e il protocollo della tua installazione:

TYPESENSE_PORT=8108
TYPESENSE_PATH=
TYPESENSE_PROTOCOL=http

Ulteriori impostazioni e definizioni dello schema per le tue collezioni Typesense si trovano nel file di configurazione config/scout.php della tua applicazione. Per maggiori informazioni su Typesense, consulta la documentazione di Typesense.

Preparare i Dati per l’Archiviazione in Typesense

Quando utilizzi Typesense, i modelli ricercabili devono definire un metodo toSearchableArray che converte la chiave primaria del modello in una stringa e la data di creazione in un timestamp UNIX:

/**
 * Ottieni l'array dei dati indicizzabili per il modello.
 *
 * @return array<string, mixed>
 */
public function toSearchableArray()
{
    return array_merge($this->toArray(),[
        'id' => (string) $this->id,
        'created_at' => $this->created_at->timestamp,
    ]);
}

Dovresti anche definire gli schemi delle tue collezioni Typesense nel file config/scout.php della tua applicazione. Uno schema di collezione descrive i tipi di dati di ogni campo ricercabile tramite Typesense. Per maggiori informazioni su tutte le opzioni di schema disponibili, consulta la documentazione di Typesense.

Se devi modificare lo schema della tua collezione Typesense dopo averlo definito, puoi eseguire scout:flush e scout:import, che elimineranno tutti i dati indicizzati esistenti e ricreeranno lo schema. Oppure, puoi usare l’API di Typesense per modificare lo schema della collezione senza rimuovere i dati indicizzati.

Se il tuo modello ricercabile supporta l’eliminazione morbida, dovresti definire un campo __soft_deleted nello schema Typesense corrispondente al modello nel file di configurazione config/scout.php della tua applicazione:

User::class => [
    'collection-schema' => [
        'fields' => [
            // ...
            [
                'name' => '__soft_deleted',
                'type' => 'int32',
                'optional' => true,
            ],
        ],
    ],
],

Parametri di Ricerca Dinamici

Typesense consente di modificare i parametri di ricerca dinamicamente quando esegui una ricerca tramite il metodo options:

use App\Models\Todo;

Todo::search('Groceries')->options([
    'query_by' => 'title, description'
])->get();

Configurazione

Configurazione degli Indici del Modello

Ogni modello Eloquent è sincronizzato con un determinato "indice" di ricerca, che contiene tutti i record ricercabili per quel modello. In altre parole, puoi pensare a ogni indice come a una tabella MySQL. Per impostazione predefinita, ogni modello viene salvato in un indice che corrisponde al nome tipico della "tabella" del modello. Solitamente, questa è la forma plurale del nome del modello; tuttavia, puoi personalizzare l’indice del modello sovrascrivendo il metodo searchableAs nel modello:

<?php

namespace App\Models;

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

class Post extends Model
{
    use Searchable;

    /**
     * Ottieni il nome dell'indice associato al modello.
     */
    public function searchableAs(): string
    {
        return 'posts_index';
    }
}

Configurare i Dati Ricercabili

Per impostazione predefinita, l’intera forma toArray di un modello verrà salvata nel suo indice di ricerca. Se desideri personalizzare i dati sincronizzati con l’indice di ricerca, puoi sovrascrivere il metodo toSearchableArray nel modello:

<?php

namespace App\Models;

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

class Post extends Model
{
    use Searchable;

    /**
     * Ottieni l'array di dati indicizzabili per il modello.
     *
     * @return array<string, mixed>
     */
    public function toSearchableArray(): array
    {
        $array = $this->toArray();

        // Personalizza l'array dei dati...

        return $array;
    }
}

Alcuni motori di ricerca come Meilisearch eseguono operazioni di filtro (>, <, ecc.) solo sui dati del tipo corretto. Quindi, quando si utilizzano questi motori di ricerca e si personalizzano i dati ricercabili, si deve assicurarsi che i valori numerici siano convertiti al tipo corretto:

public function toSearchableArray()
{
    return [
        'id' => (int) $this->id,
        'name' => $this->name,
        'price' => (float) $this->price,
    ];
}

Configurazione dei Dati Filtrabili e delle Impostazioni di Indice (Meilisearch)

A differenza degli altri driver di Scout, Meilisearch richiede di predefinire le impostazioni di ricerca dell’indice come attributi filtrabili, attributi ordinabili e altri campi di impostazioni supportati.

Gli attributi filtrabili sono quelli su cui intendi applicare filtri quando usi il metodo where di Scout, mentre gli attributi ordinabili sono quelli su cui intendi ordinare utilizzando il metodo orderBy di Scout. Per definire le impostazioni del tuo indice, modifica la sezione index-settings nella voce di configurazione meilisearch nel file di configurazione scout della tua applicazione:

use App\Models\User;
use App\Models\Flight;

'meilisearch' => [
    'host' => env('MEILISEARCH_HOST', 'http://localhost:7700'),
    'key' => env('MEILISEARCH_KEY', null),
    'index-settings' => [
        User::class => [
            'filterableAttributes'=> ['id', 'name', 'email'],
            'sortableAttributes' => ['created_at'],
            // Other settings fields...
        ],
        Flight::class => [
            'filterableAttributes'=> ['id', 'destination'],
            'sortableAttributes' => ['updated_at'],
        ],
    ],
],

Se il modello sottostante un indice specifico può essere eliminato logicamente e è incluso nell’array index-settings, Scout includerà automaticamente il supporto per filtrare i modelli eliminati logicamente su quell’indice. Se non hai altri attributi filtrabili o ordinabili da definire per un indice di modello eliminabile logicamente, puoi semplicemente aggiungere una voce vuota all’array index-settings per quel modello:

'index-settings' => [
    Flight::class => []
],

Dopo aver configurato le impostazioni dell’indice della tua applicazione, devi eseguire il comando Artisan scout:sync-index-settings. Questo comando informerà Meilisearch delle impostazioni dell’indice attualmente configurate. Per comodità, potresti voler includere questo comando nel processo di distribuzione:

php artisan scout:sync-index-settings

Configurare l’ID del Modello

Per impostazione predefinita, Scout utilizza la chiave primaria del modello come ID/chiave unici memorizzati nell’indice di ricerca. Se desideri personalizzare questo comportamento, puoi sovrascrivere i metodi getScoutKey e getScoutKeyName nel modello:

<?php

namespace App\Models;

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

class User extends Model
{
    use Searchable;

    /**
     * Ottieni il valore utilizzato per indicizzare il modello.
     */
    public function getScoutKey(): mixed
    {
        return $this->email;
    }

    /**
     * Ottieni il nome della chiave utilizzata per indicizzare il modello.
     */
    public function getScoutKeyName(): mixed
    {
        return 'email';
    }
}

Configurare i Motori di Ricerca per Modello

Durante la ricerca, Scout utilizzerà tipicamente il motore di ricerca predefinito specificato nel file di configurazione scout della tua applicazione. Tuttavia, il motore di ricerca per un modello particolare può essere cambiato sovrascrivendo il metodo searchableUsing nel modello:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Engines\Engine;
use Laravel\Scout\EngineManager;
use Laravel\Scout\Searchable;

class User extends Model
{
    use Searchable;

    /**
     * Get the engine used to index the model.
     */
    public function searchableUsing(): Engine
    {
        return app(EngineManager::class)->engine('meilisearch');
    }
}

Identificazione degli Utenti

Scout permette anche di identificare automaticamente gli utenti quando si utilizza Algolia. Associare l’utente autenticato alle operazioni di ricerca può essere utile quando visualizzi le analisi delle ricerche nel dashboard di Algolia. Puoi abilitare l’identificazione dell’utente definendo una variabile d’ambiente SCOUT_IDENTIFY come true nel file .env della tua applicazione:

SCOUT_IDENTIFY=true

Abilitando questa funzionalità, verranno inviati a Algolia anche l’indirizzo IP della richiesta e l’identificatore principale dell’utente autenticato, in modo che questi dati siano associati a qualsiasi richiesta di ricerca effettuata dall’utente.

Motori di Database e Collection

Motore Database

Al momento il motore database supporta MySQL e PostgreSQL.

Se la tua applicazione interagisce con database di piccole o medie dimensioni o ha un carico di lavoro leggero, potresti trovare più comodo iniziare con il motore "database" di Scout. Il motore database utilizzerà clausole "where like" e indici full text per filtrare i risultati dal tuo database esistente e determinare i risultati di ricerca pertinenti per la tua query.

Per utilizzare il motore database, puoi semplicemente impostare il valore della variabile d’ambiente SCOUT_DRIVER su database, oppure specificare direttamente il driver database nel file di configurazione scout della tua applicazione:

SCOUT_DRIVER=database

Una volta specificato il motore database come driver preferito, devi configurare i tuoi dati ricercabili. Poi, puoi iniziare a eseguire query di ricerca sui tuoi modelli. L’indicizzazione del motore di ricerca, come l’indicizzazione necessaria per popolare gli indici di Algolia, Meilisearch o Typesense, non è necessaria quando si utilizza il motore database.

Personalizzare le Strategie di Ricerca nel Database

Per impostazione predefinita, il motore del database esegue una query "where like" su ogni attributo del modello che hai configurato come ricercabile. Tuttavia, in alcune situazioni questo può causare scarse prestazioni. Perciò, la strategia di ricerca del motore del database può essere configurata in modo che alcune colonne specifiche utilizzino query di full text search o si limitino a vincoli "where like" per cercare i prefissi delle stringhe (example%), invece di cercare all’interno dell’intera stringa (%example%).

Per definire questo comportamento, puoi assegnare attributi PHP al metodo toSearchableArray del tuo modello. Qualsiasi colonna non assegnata ad ulteriori comportamenti di strategia di ricerca continuerà a utilizzare la strategia predefinita "where like":

use Laravel\Scout\Attributes\SearchUsingFullText;
use Laravel\Scout\Attributes\SearchUsingPrefix;

/**
 * Get the indexable data array for the model.
 *
 * @return array<string, mixed>
 */
#[SearchUsingPrefix(['id', 'email'])]
#[SearchUsingFullText(['bio'])]
public function toSearchableArray(): array
{
    return [
        'id' => $this->id,
        'name' => $this->name,
        'email' => $this->email,
        'bio' => $this->bio,
    ];
}

Prima di specificare che una colonna utilizzi vincoli di query full text, assicurati che la colonna abbia assegnato un indice full text.

Motore di Raccolta

Durante lo sviluppo locale, puoi usare i motori di ricerca Algolia, Meilisearch o Typesense, ma potrebbe essere più comodo iniziare con il motore "collection". Il motore collection utilizza clausole "where" e filtri delle raccolte sui risultati dal tuo database esistente per determinare i risultati di ricerca applicabili alla tua query. Quando usi questo motore, non è necessario "indizzare" i tuoi modelli ricercabili, poiché verranno semplicemente recuperati dal tuo database locale.

Per usare il motore collection, puoi impostare il valore della variabile d’ambiente SCOUT_DRIVER su collection, oppure specificare direttamente il driver collection nel file di configurazione scout della tua applicazione:

SCOUT_DRIVER=collection

Una volta specificato il driver collection come preferito, puoi iniziare a eseguire query di ricerca sui tuoi modelli. L’indicizzazione del motore di ricerca, come quella necessaria per popolare gli indici di Algolia, Meilisearch o Typesense, non è necessaria quando usi il motore collection.

Differenze rispetto al Motore di Database

A prima vista, i motori "database" e "collections" sono abbastanza simili. Entrambi interagiscono direttamente con il tuo database per recuperare i risultati di ricerca. Tuttavia, il motore delle collection non utilizza indici full text o clausole LIKE per trovare i record corrispondenti. Invece, recupera tutti i possibili record e usa l’helper Str::is di Laravel per determinare se la stringa di ricerca esiste nei valori degli attributi del modello.

Il motore delle collection è il motore di ricerca più portabile poiché funziona con tutti i database relazionali supportati da Laravel (inclusi SQLite e SQL Server); tuttavia, è meno efficiente rispetto al motore di database di Scout.

Indicizzazione

Importazione in Batch

Se stai installando Scout in un progetto esistente, potresti già avere record nel database che devi importare nei tuoi indici. Scout fornisce un comando Artisan scout:import che puoi usare per importare tutti i tuoi record esistenti nei tuoi indici di ricerca:

php artisan scout:import "App\Models\Post"

Il comando flush può essere utilizzato per rimuovere tutti i record di un modello dai tuoi indici di ricerca:

php artisan scout:flush "App\Models\Post"

Modifica della Query di Importazione

Se desideri modificare la query utilizzata per recuperare tutti i tuoi modelli per l’importazione in batch, puoi definire un metodo makeAllSearchableUsing nel tuo modello. Questo è un ottimo posto per aggiungere qualsiasi caricamento eager delle relazioni necessario prima di importare i tuoi modelli:

use Illuminate\Database\Eloquent\Builder;

/**
 * Modifica la query usata per recuperare i modelli quando si rendono tutti i modelli ricercabili.
 */
protected function makeAllSearchableUsing(Builder $query): Builder
{
    return $query->with('author');
}

Il metodo makeAllSearchableUsing potrebbe non essere applicabile quando si utilizza una coda per importare i modelli in batch. Le relazioni non vengono ristabilite quando le collezioni di modelli sono processate dai job.

Aggiungere Record

Una volta aggiunto il trait Laravel\Scout\Searchable a un modello, tutto ciò che devi fare è save o create un’istanza del modello e verrà automaticamente aggiunto al tuo indice di ricerca. Se hai configurato Scout per usare le code, questa operazione verrà eseguita in background dal tuo worker di coda:

use App\Models\Order;

$order = new Order;

// ...

$order->save();

Aggiungere Record tramite Query

Se desideri aggiungere una collezione di modelli al tuo indice di ricerca tramite una query Eloquent, puoi concatenare il metodo searchable alla query Eloquent. Il metodo searchable divide i risultati della query e aggiunge i record al tuo indice di ricerca. Inoltre, se hai configurato Scout per usare le code, tutti i chunk verranno importati in background dai tuoi worker della coda:

use App\Models\Order;

Order::where('price', '>', 100)->searchable();

Puoi anche chiamare il metodo searchable su un’istanza di relazione Eloquent:

$user->orders()->searchable();

Oppure, se hai già una collezione di modelli Eloquent in memoria, puoi chiamare il metodo searchable sull’istanza della collezione per aggiungere le istanze dei modelli al relativo indice:

$orders->searchable();

Il metodo searchable può essere considerato un’operazione di "upsert". In altre parole, se il record del modello è già nel tuo indice, verrà aggiornato. Se non esiste nell’indice di ricerca, verrà aggiunto all’indice.

Aggiornare i Record

Per aggiornare un modello ricercabile, devi solo aggiornare le proprietà dell’istanza del modello e save il modello nel tuo database. Scout salverà automaticamente le modifiche nel tuo indice di ricerca:

use App\Models\Order;

$order = Order::find(1);

// Aggiorna l'ordine...

$order->save();

Puoi anche utilizzare il metodo searchable su un’istanza di query Eloquent per aggiornare una collezione di modelli. Se i modelli non esistono nel tuo indice di ricerca, verranno creati:

Order::where('price', '>', 100)->searchable();

Se vuoi aggiornare i record dell’indice di ricerca per tutti i modelli in una relazione, puoi chiamare searchable sull’istanza della relazione:

$user->orders()->searchable();

Oppure, se hai già una collezione di modelli Eloquent in memoria, puoi chiamare il metodo searchable sull’istanza della collezione per aggiornare le istanze dei modelli nel loro indice corrispondente:

$orders->searchable();

Modificare i Record Prima dell’Importazione

A volte potresti dover preparare la collezione di modelli prima che vengano resi ricercabili. Ad esempio, potresti voler caricare anticipatamente una relazione in modo che i dati della relazione possano essere aggiunti in modo efficiente al tuo indice di ricerca. Per ottenere questo, definisci un metodo makeSearchableUsing sul modello corrispondente:

use Illuminate\Database\Eloquent\Collection;

/**
 * Modifica la collezione di modelli che viene resa ricercabile.
 */
public function makeSearchableUsing(Collection $models): Collection
{
    return $models->load('author');
}

Rimozione dei Record

Per rimuovere un record dal tuo indice puoi semplicemente delete il modello dal database. Questo può essere fatto anche se stai usando modelli soft deleted:

use App\Models\Order;

$order = Order::find(1);

$order->delete();

Se non vuoi recuperare il modello prima di eliminare il record, puoi usare il metodo unsearchable su un’istanza di query Eloquent:

Order::where('price', '>', 100)->unsearchable();

Se desideri rimuovere i record dell’indice di ricerca per tutti i modelli in una relazione, puoi invocare unsearchable sull’istanza della relazione:

$user->orders()->unsearchable();

Oppure, se hai già una collezione di modelli Eloquent in memoria, puoi chiamare il metodo unsearchable sull’istanza della collezione per rimuovere le istanze del modello dal loro indice corrispondente:

$orders->unsearchable();

Per rimuovere tutti i record del modello dal loro indice corrispondente, puoi invocare il metodo removeAllFromSearch:

Order::removeAllFromSearch();

Pausa dell’indicizzazione

A volte potresti dover eseguire una serie di operazioni Eloquent su un modello senza sincronizzare i dati del modello con il tuo indice di ricerca. Puoi fare questo usando il metodo withoutSyncingToSearch. Questo metodo accetta una singola closure che verrà eseguita immediatamente. Qualsiasi operazione sul modello all’interno della closure non verrà sincronizzata con l’indice del modello:

use App\Models\Order;

Order::withoutSyncingToSearch(function () {
    // Esegui azioni sul modello...
});

Istanze di Modelli Ricercabili Condizionatamente

A volte potrebbe essere necessario rendere un modello ricercabile solo sotto certe condizioni. Ad esempio, immagina di avere il modello App\Models\Post che può essere in uno dei due stati: "bozza" e "pubblicato". Potresti voler permettere la ricerca solo ai post "pubblicati". Per fare questo, puoi definire un metodo shouldBeSearchable nel tuo modello:

/**
 * Determina se il modello deve essere ricercabile.
 */
public function shouldBeSearchable(): bool
{
    return $this->isPublished();
}

Il metodo shouldBeSearchable viene applicato solo quando si manipolano i modelli tramite i metodi save e create, query o relazioni. Rendere direttamente ricercabili modelli o collezioni usando il metodo searchable sovrascriverà il risultato del metodo shouldBeSearchable.

Il metodo shouldBeSearchable non è applicabile quando si usa il motore "database" di Scout, poiché tutti i dati ricercabili sono sempre archiviati nel database. Per ottenere un comportamento simile usando il motore database, dovresti usare le clausole where invece.

Ricerca

Puoi iniziare a cercare un modello usando il metodo search. Il metodo di ricerca accetta una singola stringa che verrà utilizzata per cercare nei tuoi modelli. Successivamente, dovresti concatenare il metodo get alla query di ricerca per recuperare i modelli Eloquent che corrispondono alla query di ricerca:

use App\Models\Order;

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

Poiché le ricerche di Scout restituiscono una collection di modelli Eloquent, puoi anche restituire direttamente i risultati da una rotta o un controller e verranno automaticamente convertiti in JSON:

use App\Models\Order;
use Illuminate\Http\Request;

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

Se desideri ottenere i risultati di ricerca grezzi prima che vengano convertiti in modelli Eloquent, puoi usare il metodo raw:

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

Indici Personalizzati

Le query di ricerca vengono solitamente eseguite sull’indice specificato dal metodo searchableAs del modello. Tuttavia, puoi usare il metodo within per specificare un indice personalizzato su cui eseguire la ricerca:

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

Clausole Where

Scout ti permette di aggiungere semplici clausole "where" alle tue query di ricerca. Attualmente, queste clausole supportano solo controlli di uguaglianza numerica di base e sono principalmente utili per delimitare le query di ricerca per ID proprietario:

use App\Models\Order;

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

Inoltre, il metodo whereIn può essere usato per verificare che il valore di una determinata colonna sia contenuto nell’array fornito:

$orders = Order::search('Star Trek')->whereIn(
    'status', ['open', 'paid']
)->get();

Il metodo whereNotIn verifica che il valore della colonna specificata non sia contenuto nell’array fornito:

$orders = Order::search('Star Trek')->whereNotIn(
    'status', ['closed']
)->get();

Poiché un indice di ricerca non è un database relazionale, al momento non sono supportate clausole "where" più avanzate.

Se la tua applicazione utilizza Meilisearch, devi configurare gli attributi filtrabili della tua applicazione prima di utilizzare le clausole "where" di Scout.

Paginazione

Oltre a recuperare una collezione di modelli, puoi paginare i risultati della ricerca utilizzando il metodo paginate. Questo metodo restituirà un’istanza di Illuminate\Pagination\LengthAwarePaginator, proprio come se avessi paginato una tradizionale query Eloquent:

use App\Models\Order;

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

Puoi specificare quanti modelli recuperare per pagina passando la quantità come primo argomento al metodo paginate:

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

Una volta che hai recuperato i risultati, puoi mostrarli e generare i link delle pagine usando Blade, proprio come se avessi paginato una tradizionale query Eloquent:

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

{{ $orders->links() }}

Certamente, se desideri ottenere i risultati della paginazione in formato JSON, puoi restituire direttamente l’istanza del paginator da una route o controller:

use App\Models\Order;
use Illuminate\Http\Request;

Route::get('/orders', function (Request $request) {
    return Order::search($request->input('query'))->paginate(15);
});

Dal momento che i motori di ricerca non sono a conoscenza delle definizioni degli scope globali del tuo modello Eloquent, non dovresti utilizzare gli scope globali nelle applicazioni che utilizzano la paginazione di Scout. Oppure, dovresti ricreare i vincoli dello scope globale quando effettui ricerche tramite Scout.

Soft Deleting

Se i tuoi modelli indicizzati utilizzano il soft deleting e hai bisogno di cercare i modelli soft eliminati, imposta l’opzione soft_delete nel file di configurazione config/scout.php su true:

'soft_delete' => true,

Quando questa opzione è true, Scout non rimuoverà i modelli soft eliminati dall’indice di ricerca. Invece, imposterà un attributo nascosto __soft_deleted sul record indicizzato. Successivamente, puoi usare i metodi withTrashed o onlyTrashed per recuperare i record soft eliminati durante la ricerca:

use App\Models\Order;

// Includi i record eliminati quando recuperi i risultati...
$orders = Order::search('Star Trek')->withTrashed()->get();

// Includi solo i record eliminati quando recuperi i risultati...
$orders = Order::search('Star Trek')->onlyTrashed()->get();

Quando un modello soft eliminato viene cancellato definitivamente usando forceDelete, Scout lo rimuoverà automaticamente dall’indice di ricerca.

Personalizzazione delle Ricerche del Motore

Se hai bisogno di personalizzare in modo avanzato il comportamento di ricerca di un motore, puoi passare una closure come secondo argomento al metodo search. Ad esempio, potresti utilizzare questo callback per aggiungere dati di geolocalizzazione alle opzioni di ricerca prima che la query venga inviata ad Algolia:

use Algolia\AlgoliaSearch\SearchIndex;
use App\Models\Order;

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

Personalizzare la Query dei Risultati Eloquent

Dopo che Scout recupera una lista di modelli Eloquent corrispondenti dal motore di ricerca della tua applicazione, Eloquent viene usato per recuperare tutti i modelli corrispondenti tramite le loro chiavi primarie. Puoi personalizzare questa query invocando il metodo query. Il metodo query accetta una closure che riceverà l’istanza del query builder Eloquent come argomento:

use App\Models\Order;
use Illuminate\Database\Eloquent\Builder;

$orders = Order::search('Star Trek')
    ->query(fn (Builder $query) => $query->with('invoices'))
    ->get();

Poiché questa callback viene invocata dopo che i modelli rilevanti sono già stati recuperati dal motore di ricerca della tua applicazione, il metodo query non dovrebbe essere usato per "filtrare" i risultati. Invece, dovresti usare le clausole where di Scout.

Motori personalizzati

Scrivere il motore

Se uno dei motori di ricerca Scout integrati non soddisfa le tue esigenze, puoi creare un motore personalizzato e registrarlo con Scout. Il tuo motore dovrebbe estendere la classe astratta Laravel\Scout\Engines\Engine. Questa classe astratta contiene otto metodi che il tuo motore personalizzato deve implementare:

    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(Builder $builder, $results, $model);
    abstract public function getTotalCount($results);
    abstract public function flush($model);

Potrebbe esserti utile esaminare le implementazioni di questi metodi nella classe Laravel\Scout\Engines\AlgoliaEngine. Questa classe ti offrirà un buon punto di partenza per imparare come implementare ciascuno di questi metodi nel tuo motore.

Registrazione del motore

Una volta che hai scritto il tuo motore personalizzato, puoi registrarlo con Scout utilizzando il metodo extend del manager dei motori di Scout. Il manager dei motori di Scout può essere risolto dal contenitore di servizi di Laravel. Dovresti chiamare il metodo extend dal metodo boot della tua classe App\Providers\AppServiceProvider o da qualsiasi altro provider di servizi utilizzato dalla tua applicazione:

use App\ScoutExtensions\MySqlSearchEngine;
use Laravel\Scout\EngineManager;

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

Una volta che il tuo motore è stato registrato, puoi specificarlo come driver predefinito di Scout nel file di configurazione config/scout.php della tua applicazione:

'driver' => 'mysql',
Lascia un commento

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *