Prologo
Primi Passi
Architettura
Le Basi
- Routing
- Middleware
- Protezione da CSRF
- Controller
- Richieste
- Risposte
- Views
- Blade
- Vite
- URL
- Sessioni
- Validazione
- Errori
- Logging
Approfondimenti
- Artisan
- Broadcasting
- Cache
- Collezioni
- Concorrenza
- Contesto
- Contratti
- Eventi
- File System
- Helpers
- Client HTTP
- Localizzazione
- Notifiche
- Sviluppo di Package
- Processi
- Code
- Rate-limiting
- Stringhe
- Scheduling di Task
Sicurezza
Database
Eloquent ORM
Testing
Package
Scout
- Introduzione
- Installazione
- Prerequisiti del Driver
- Configurazione
- Motori di Database e Collection
- Indicizzazione
- Ricerca
- Motori personalizzati
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',