Фільтрування результатів за допомогою LIKE


16

Розглянемо ці три струни "сіна":

а) foo bar

б) welcome to foo bar industries

в) foo barer

А тепер моя "голка":

foo bar

(Хе)

Я хотів би, щоб мій фільтр збігав мою голку зі стружками сіна a & b, але не c. Я намагався:

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

Але вищезгадані збіги з c.

Я також спробував:

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

Наведене вище відповідає лише b.

Будь-яка допомога дуже цінується.

Відповіді:


37

Спробуйте це і подивіться, чи підходить воно:

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

Передача другого параметра у вигляді масиву масивів об'єднає умови використання OR


Це працює :) Не знав про фокус масиву, дякую.
beingalex

З нестандартними моделями / моделями, які addAttributeToFilterне використовуються, слід замінити їх addFieldToFilter.
jvalanen

Чи є спосіб визначити, який масив повернув результат? Я використовую цей метод для пошуку колекції користувальницької моделі (ім'я, опис, поля альтернативної імені), і я хотів би дізнатися, чи результат потрапив через опис (щоб включити додатковий елемент інтерфейсу в результати пошуку).
pspahn

3
@pspahn Не прямий вперед. Ви можете провести цикл результатів після виконання вибору та перевірити, чи знайдена голка в будь-якому з потрібних полів.
Маріус

9

Можливим рішенням є використання REGEXPзамість LIKE:

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

З документації на MySQL :

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

Ці маркери означають межі слів. Вони відповідають початку та кінці слів відповідно. Слово - це послідовність символів слова, яким не передують і не слідують символи слова. Символ слова - це буквено-цифровий символ у класі alnum або підкреслення (_).

Зауважте, що якщо ви $needleможете містити символи, які мають особливі значення в регулярних виразах POSIX, вам потрібно уникнути їх. Дивіться також: /programming/4024188/php-function-to-escape-mysql-regexp-syntax


3

Прийнята відповідь не працює належним чином. Це перевірка лише місця перед текстом та після нього.

Припустимо, у вас є наступний список

  • Куртка
  • Літня куртка
  • Зимова куртка

Тепер якщо ви спробуєте пошукати куртку за допомогою прийнятої відповіді, вона поверне лише літню куртку та зимову куртку

Я думаю, що наступне рішення краще

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

Це не охоплює випадок (c) з питання (тобто також відповідає "підряднику"). Натомість ['eq' => $needle]може бути додана четверта умова, щоб знайти точні збіги (а краще, скористайтеся рішенням регулярного вираження, яке знаходить усі межі, а не лише пробіли)
Фабіан Шменглер

вище код здатний знайти точні збіги. Я перевірив це
Дінеш Ядав

Я в цьому не сумнівався. Але знаходить більше, чого не слід. Принаймні, якщо у вас є ті ж вимоги, що і в оригінальному запитанні: Не знаходите "foo barer" під час пошуку "foo bar"
Fabian Schmengler

Так, ти правий. Прийнята відповідь не працювала для мене належним чином, тому я запропонував простий однорядковий фільтр для отримання аналогічних елементів.
Дінеш Ядав
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.