Jump to content
Sign in to follow this  
lady R

Query di ricerca MySQLi

Recommended Posts

Ciao!

 

Ho quasi finito il mio blog, e sto implementando una funzione di ricerca tra gli articoli.

 

La query attualmente è questa (non prevede paginazione attualmente, la aggiungerò dopo):

 

SELECT * FROM `articles` WHERE LOWER(`title`) LIKE LOWER('%$keyword%') OR LOWER(`introtext`) LIKE LOWER('%$keyword%') OR LOWER(`fulltext`) LIKE LOWER('%$keyword%') ORDER by date DESC LIMIT 0,100

 

dove $keyword sono una o più parole cercate dall'utente.

 

La mia domanda è:

 

Come posso fare per far sì che la query cerchi la presenza di una o più parole presenti in $keyword?

 

Vorrei che cercando "mela pera" mi trovi gli articoli riguardanti (le mele), (le pere) o (le mele e le pere).

Sapete aiutarmi?

 

Grazie

Share this post


Link to post
Share on other sites

Non l'ho testato ma una cosa del genere funzionerà sicuramente :sisi:

 

<?php
   $Keywords = 'ciao banana'; //Supponiamo che sia $_REQUEST['Keywords']
   $Parole = explode(" ", $Keywords);

       if (is_array($Parole)) { //Sicuramente sono più parole....
       foreach ($Parole as $Chiave => $Valore) {
           $QueryWhere .= " OR (Campo1 Like LOWER '%$Valore%') ";
       }
       } else {
           //E' una sola parola....
           $QueryWhere = " OR (Campo1 Like LOWER '%$Keywords%') ";
       }

   $QueryCompleta = "SELECT * FROM articles WHERE 1 ".$QueryWhere;
   echo $QueryCompleta;
?>

 

:approved:

Share this post


Link to post
Share on other sites

Sposta tutti i LOWER('%$keyword%') lato PHP facendo fare a PHP la conversione in minuscolo, altrimenti se ti arriva una stringa del tipo

 

Pippo

 

ed una del tipo

 

pippO

 

nonostante siano perfettamente identiche come risultato, MySQL non ti utilizza la cache in quanto query differenti come struttura

 

LOWER('Pippo')

e

LOWER('pippO')

Share this post


Link to post
Share on other sites
Non l'ho testato ma una cosa del genere funzionerà sicuramente :sisi:

 

<?php
   $Keywords = 'ciao banana'; //Supponiamo che sia $_REQUEST['Keywords']
   $Parole = explode(" ", $Keywords);

       if (is_array($Parole)) { //Sicuramente sono più parole....
       foreach ($Parole as $Chiave => $Valore) {
           $QueryWhere .= " OR (Campo1 Like LOWER '%$Valore%') ";
       }
       } else {
           //E' una sola parola....
           $QueryWhere = " OR (Campo1 Like LOWER '%$Keywords%') ";
       }

   $QueryCompleta = "SELECT * FROM articles WHERE 1 ".$QueryWhere;
   echo $QueryCompleta;
?>

 

:approved:

 

Avevo pensato anche io a qualcosa di simile però speravo ci fosse un modo più pulito, non so, una funzione specifica di MySQL, proverò così comunque. Grazie

 

Sposta tutti i LOWER('%$keyword%') lato PHP facendo fare a PHP la conversione in minuscolo, altrimenti se ti arriva una stringa del tipo

 

Pippo

 

ed una del tipo

 

pippO

 

nonostante siano perfettamente identiche come risultato, MySQL non ti utilizza la cache in quanto query differenti come struttura

 

LOWER('Pippo')

e

LOWER('pippO')

 

Non posso fare come dici tu, perché nel database ci sono le maiuscole, se io cerco una parola minuscola non funziona se nel database è maiuscola, no?

Share this post


Link to post
Share on other sites

Ho applicato il metodo indicatomi da @tecnolive con le dovute modifiche:

 

$words = explode(" ", $keywords); 
if (is_array($words)) { 
 foreach ($words as &$keyword) {
   $QueryWhere .= " OR LOWER(`title`) LIKE LOWER('%$keyword%') OR LOWER(`introtext`) LIKE LOWER('%$keyword%') OR LOWER(`fulltext`) LIKE LOWER('%$keyword%') ";
 }
} else {
 $QueryWhere = " OR LOWER(`title`) LIKE LOWER('%$keyword%') OR LOWER(`introtext`) LIKE LOWER('%$keyword%') OR LOWER(`fulltext`) LIKE LOWER('%$keyword%') ";
}

$query = "SELECT * FROM `articles` WHERE `id` = '-1' " . $QueryWhere . " ORDER by date DESC LIMIT 0,100;";

$result = $mysqli->query($query) or die($mysqli->error.__LINE__);

 

Al posto di inserire dopo WHERE un 1 ho messo id = -1 perché altrimenti mi prendeva tutte le righe come buone e non andava bene. id = -1 è l'unica condizione che mi è venuta in mente che non desse mai risultati.

Share this post


Link to post
Share on other sites
Ho applicato il metodo indicatomi da @tecnolive con le dovute modifiche:

 

$words = explode(" ", $keywords); 
if (is_array($words)) { 
 foreach ($words as &$keyword) {
   $QueryWhere .= " OR LOWER(`title`) LIKE LOWER('%$keyword%') OR LOWER(`introtext`) LIKE LOWER('%$keyword%') OR LOWER(`fulltext`) LIKE LOWER('%$keyword%') ";
 }
} else {
 $QueryWhere = " OR LOWER(`title`) LIKE LOWER('%$keyword%') OR LOWER(`introtext`) LIKE LOWER('%$keyword%') OR LOWER(`fulltext`) LIKE LOWER('%$keyword%') ";
}

$query = "SELECT * FROM `articles` WHERE `id` = '-1' " . $QueryWhere . " ORDER by date DESC LIMIT 0,100;";

$result = $mysqli->query($query) or die($mysqli->error.__LINE__);

 

Al posto di inserire dopo WHERE un 1 ho messo id = -1 perché altrimenti mi prendeva tutte le righe come buone e non andava bene. id = -1 è l'unica condizione che mi è venuta in mente che non desse mai risultati.

 

?

 

Ma togliere `id` = '-1' e l'OR iniziale di entrambe le righe nell'if no?

 

Inoltre concordo con guest, usa strtolower di PHP invece di LOWER('%$keyword%') ...

Share this post


Link to post
Share on other sites

Non posso togliere gli OR iniziali, sennò la query non funziona più. Dovrei aggiungere al loop un controllo per vedere se si tratta del primo giro, ma è più semplice mettere quel id = -1

 

Non posso usare strtolower come ho già spiegato nel mio post sopra. Amenoché non vi venga in mente un modo per usare strtolower nel testo che viene prelevato da MySQL durante la query e non dopo

Share this post


Link to post
Share on other sites
Non posso togliere gli OR iniziali, sennò la query non funziona più. Dovrei aggiungere al loop un controllo per vedere se si tratta del primo giro, ma è più semplice mettere quel id = -1

 

Non posso usare strtolower come ho già spiegato nel mio post sopra. Amenoché non vi venga in mente un modo per usare strtolower nel testo che viene prelevato da MySQL durante la query e non dopo

 

In merito allo strtolower, intendo una cosa del genere


$esempio = "LOWER(`title`) LIKE '%".strtolower($keyword)."%' OR LOWER(`introtext`) LIKE '%".strtolower($keyword%)."%' OR LOWER(`fulltext`) LIKE '%".strtolower($keyword%)."%'";

Share this post


Link to post
Share on other sites

Ah ok! Pensavo bisognasse applicarlo anche al campo del mysql, invece li va bene tenere LOWER quindi.

Faccio subito grazie.

 

PS, ho messo al posto che richiamare strtolower ad ogni occorrenza, nella riga precedente alla query un

 

$keyword = strtolower($keyword);

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×