Filtraggio dei risultati usando LIKE


16

Considera queste tre stringhe "pagliaio":

un) foo bar

b) welcome to foo bar industries

c) foo barer

E ora il mio "ago":

foo bar

(Heh)

Vorrei che il mio filtro corrispondesse al mio ago con le corde del pagliaio a & b ma non c. Ho provato:

$collection->addAttributeToFilter('name', array('like' => '%'.$needle.'%'));

Ma quanto sopra corrisponde a c.

Ho anche provato:

$collection->addAttributeToFilter('name', array('like' => '% '.$needle.' %')); // Note the spaces

Quanto sopra corrisponde solo a b.

Ogni aiuto è molto apprezzato.

Risposte:


37

Fai una prova e vedi se si adatta:

$collection->addAttributeToFilter('name', array(
    array('like' => '% '.$needle.' %'), //spaces on each side
    array('like' => '% '.$needle), //space before and ends with $needle
    array('like' => $needle.' %') // starts with needle and space after
));

Passare il secondo parametro come una matrice di array concatenerà le condizioni usando OR


Funziona :) Non sapevo del trucco dell'array, grazie.
— beingalex,

Con i modelli personalizzati / non-eav addAttributeToFilterdevono essere sostituiti con addFieldToFilter.
— jvalanen,

C'è un modo per determinare quale array ha restituito un risultato? Sto usando questo metodo per cercare una collezione di modelli personalizzati (nome, descrizione, campi nome_alternativo) e mi piacerebbe sapere se il risultato è stato colpito a causa della descrizione (per includere un elemento dell'interfaccia utente aggiuntivo nei risultati di ricerca).
— pspahn

3
@pspahn Non è semplice. È possibile scorrere i risultati dopo aver eseguito la selezione e verificare se l'ago viene trovato in uno dei campi desiderati.
— Marius

9

Una possibile soluzione è utilizzare REGEXPinvece di LIKE:

$collection->addAttributeToFilter('name', array('regexp' => '[[:<:]]'.$needle.'[[:>:]]'));

Dalla documentazione di MySQL :

[[: <:]], [[:>:]]

Questi marcatori indicano i confini delle parole. Corrispondono all'inizio e alla fine delle parole, rispettivamente. Una parola è una sequenza di caratteri parola che non è preceduta o seguita da caratteri parola. Un carattere parola è un carattere alfanumerico nella classe alnum o un trattino basso (_).

Nota che se $needlepuò contenere caratteri che hanno significati speciali nelle espressioni regolari POSIX, devi evitarli. Vedi anche: /programming/4024188/php-function-to-escape-mysql-regexp-syntax


3

La risposta accettata non funziona correttamente. Controlla solo lo spazio prima e dopo il testo.

Supponiamo che tu abbia il seguente elenco

  • Giacca
  • Giacca estiva
  • Giacca invernale

Ora se provi a cercare con la giacca utilizzando la risposta accettata, verranno restituiti solo Summer Jacket e Winter Jacket

Penso che seguire la soluzione sia migliore

$collection->addAttributeToFilter('name', array('like' => '%' . $needle. '%'));

Non coprirebbe il caso (c) della domanda (cioè corrisponderebbe anche al "rivestimento"). Invece, una quarta condizione ['eq' => $needle]potrebbe essere aggiunta per trovare corrispondenze esatte (o meglio, usare la soluzione regex che trova tutti i confini, non solo gli spazi)
— Fabian Schmengler

sopra il codice è in grado di trovare le corrispondenze esatte. L'ho controllato
— Dinesh Yadav il

Non ne dubitavo. Ma trova di più, cosa che non dovrebbe. Almeno se hai gli stessi requisiti della domanda originale: non trovare "foo barer" quando cerchi "foo bar"
— Fabian Schmengler

Si hai ragione. La risposta accettata non funzionava correttamente per me, quindi ho suggerito il semplice filtro a una riga per ottenere gli oggetti allo stesso modo.
— Dinesh Yadav,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.