Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Implementare la ricerca dei prodotti

Analizziamo i principali approcci utilizzabili con il DBMS MySQL per implementare la ricerca di prodotti in un e-commerce basato sul framework Laravel
Analizziamo i principali approcci utilizzabili con il DBMS MySQL per implementare la ricerca di prodotti in un e-commerce basato sul framework Laravel
Link copiato negli appunti

In questo articolo vedremo come aggiungere la funzionalità di ricerca al nostro sito confrontando alcune possibilità offerte da MySQL. La prima possibilità riguarda l'uso della clausola LIKE che ricerca una corrispondenza per pattern (schema) in un campo specifico di una tabella che abbia come valore un tipo stringa (ad esempio VARCHAR o TEXT).

Il token che accompagna questa clausola, il carattere %, ha un funzionamento analoga al carattere wildcard del comando Unix grep. Se ad esempio volessimo selezionare tutti i prodotti il cui nome inizia con la stringa PC, dovremmo scrivere:

SELECT * FROM products WHERE title LIKE 'PC%';

In questo caso il token wildcard sta ad indicare che la stringa ricercata può essere seguita da qualsiasi carattere. Nell'esempio la corrispondenza è letterale e case-sensitive, quindi se il nome inizia con la stringa pc o Pc, questo verrà ignorato e non verrà restituito alcun risultato.

Analogamente se avessimo voluto selezionare i prodotti il cui nome termina con la stringa PC, avremmo dovuto scrivere:

SELECT * FROM products WHERE title LIKE '%PC';

Infine se avessimo considerato la stringa PC come parola, avremmo dovuto scrivere tale clausola usando il token wildcard all'inizio e alla fine della stringa, in questo modo:

SELECT * FROM products WHERE title LIKE '%PC%';

LIKE non è una soluzione molto flessibile perché di fatto limita quello che l'utente può inserire nel campo di ricerca e costringe ad un laborioso processo di normalizzazione della stringa di ricerca prima che questa possa essere usata in una query.

Come altra alternativa MySQL consente di utilizzare le espressioni regolari per cercare corrispondenze nei campi di una tabella.

L'operatore REGEXP, ad esempio, consente di usare le espressioni regolari di tipo PCRE compatibile per effettuare una ricerca. Se ad esempio volessimo selezionare tutti i prodotti il cui nome inizia con la stringa PC, dovremmo scrivere:

SELECT * FROM products WHERE title REGEXP '^PC';

In questo caso il modificatore ^ delle espressioni regolari indica che la corrispondenza dovrà essere cercata all'inizio della stringa. Rispetto alla precedente soluzione, una differenza importante è che questo operatore non è case-sensitive, quindi la ricerca di stringhe come pc, PC o pC produrranno gli stessi risultati.

Analogamente se avessimo voluto selezionare i prodotti il cui nome termina con PC, avremmo dovuto scrivere:

SELECT * FROM products WHERE title REGEXP 'PC$';

Infine se avessimo considerato la stringa PC come parola, avremmo dovuto scrivere:

SELECT * FROM products WHERE title REGEXP 'PC';

Questo approccio è relativamente più flessibile e modulabile rispetto a quello visto in precedenza, ma resta comunque vincolato ai limiti delle espressioni regolari che non si adattano bene alla natura stessa del linguaggio naturale.

Per ovviare a questi limiti, in Laravel possiamo adottare l'approccio basato sulla ricerca full text.

In MySQL la ricerca full text sfrutta gli indici creati in una tabella che abilitano tale tipo di ricerca specificando il nome delle colonne. Quindi occorre creare uno o più indici full text su una tabella.

ALTER TABLE products
ADD FULLTEXT(title, content, description);

In questo caso abbiamo aggiunto tre indici full text sul nome, il contenuto e la descrizione del prodotto. Per sfruttare questa caratteristica in Laravel dobbiamo fare uso del metodo whereRaw() delle collezioni Eloquent per poter specificare una clausola WHERE usando direttamente un'espressione MySQL che fa uso degli operatori MATCH (che specifica le colonne da usare nella ricerca) e AGAINST (che specifica il termine della ricerca).

Quindi possiamo aggiungere il seguente metodo al nostro controller principale.

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Product;
class ShopController
{
    public function search(Request $request)
    {
        $query = $request->get('s');
        $products = Product::whereRaw('MATCH (title, content, description) AGAINST (?)' , [ $query ])->paginate(10)->setPath ( '' );
        $pagination = $products->appends([
            'q' => $query
        ]);
        return view('search', [
            'title' => 'Risultati della ricerca',
            'description' => 'Risultati della ricerca',
            'products' => $products
        ])->withQuery ( $query );
    }
}

Nel codice precedente, la query è contenuta nel parametro s della richiesta e viene usata come termine della ricerca. Stiamo restituendo i risultati con la paginazione e di conseguenza dobbiamo aggiungere la query string alla nostra route in modo tale da consentire alla funzionalità di paginazione di Laravel di operare correttamente.

Conclusione

Abbiamo passato in rassegna i tre approcci principali che possiamo usare in MySQL con Laravel per implementare la ricerca dei prodotti e abbiamo visto come l'approccio full text sia quello che meglio si adatta alle nostre esigenze.

Ti consigliamo anche