Sonuçları LIKE kullanarak filtreleme


16

Şu üç "samanlık" dizesini göz önünde bulundurun:

a) foo bar

b) welcome to foo bar industries

c) foo barer

Ve şimdi "iğnem":

foo bar

(Hah)

Filtremin haystack dizeleri a & b ile eşleşmesini istiyorum ama c değil. Denedim:

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

Ancak yukarıdaki c ile eşleşir.

Ayrıca denedim:

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

Yukarıdaki sadece b ile eşleşir.

Herhangi bir yardım çok takdir edilmektedir.

Yanıtlar:


37

Bunu deneyin ve uyup uymadığına bakın:

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

İkinci parametreyi bir dizi dizisi olarak geçirmek, koşulları kullanarak OR


Bu işe yarar :) Dizi hilesi hakkında bilmiyordum, teşekkürler.
beingalex

Özel / eav olmayan modellerle addAttributeToFilterdeğiştirilmelidir addFieldToFilter.
jvalanen

Hangi dizinin sonuç döndürdüğünü belirlemenin bir yolu var mı? Özel bir model koleksiyonu (ad, açıklama, alternatif_adı alanları) aramak için bu yöntemi kullanıyorum ve sonuç nedeniyle (arama sonuçlarına ek UI öğesi eklemek için) sonuç nedeniyle vurulduğunu bilmek istiyorum.
pspahn

3
@pspahn Basit bir ileri değil. Seçim yapıldıktan sonra sonuçlar arasında gezinebilir ve iğnenin istediğiniz alanlardan herhangi birinde bulunup bulunmadığını kontrol edebilirsiniz.
Marius

9

Olası bir çözüm aşağıdakiler REGEXPyerine kullanmaktır LIKE:

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

Gönderen MySQL belgelerinde :

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

Bu işaretçiler kelime sınırlarını temsil eder. Sırasıyla kelimelerin başlangıcını ve sonunu eşleştirirler. Bir kelime, öncesinde kelime karakterleri olmayan veya onu izleyen kelime karakterleri dizisidir. Sözcük karakteri, alnum sınıfındaki alfasayısal bir karakter veya alt çizgi (_).

Not eğer $needlePOSIX normal ifadelerde özel anlamları vardır karakter içerebilir, bunları kaçmak gerekir. Ayrıca bkz: /programming/4024188/php-function-to-escape-mysql-regexp-syntax


3

Kabul edilen cevap düzgün çalışmıyor. Metinden önce ve sonra yalnızca alanı kontrol ediyor.

Varsayalım, aşağıdaki listeniz var

  • Ceket
  • Yazlık Ceket
  • Kış ceketi

Kabul edilen yanıtı kullanarak ceketle arama yapmaya çalışırsanız , sadece Yaz Ceket ve Kış Ceketini döndürür

Bence çözümü takip etmek daha iyi

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

Sorudan (c) vakasını kapsamaz (yani "mantolama" ile eşleşir). Bunun yerine, ['eq' => $needle]tam eşleşmeleri bulmak için dördüncü bir koşul eklenebilir (veya daha iyisi, yalnızca boşlukları değil tüm sınırları bulan normal ifade çözümünü kullanın)
Fabian Schmengler

Yukarıdaki kod tam eşleşmeleri bulabilir. Kontrol ettim
Dinesh Yadav

Bundan şüphe etmedim. Ama daha fazla bulur, ki olmamalıdır. En azından orijinal soru ile aynı gereksinimleri varsa: "foo bar" ararken "foo barer" bulmak
Fabian Schmengler

Evet haklısın. Kabul edilen cevap benim için düzgün çalışmadı, bu yüzden benzer öğeleri almak için tek satırlık basit bir filtre önerdim.
Dinesh Yadav
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.