Çoklu Sorgularda Aynı Verileri Bir Defa Gösterme - Laravel

09.09.2018

131 Okunma

0 Favori

0 Yorum

Merhabalar, uzun bir aradan sonra derleyip topladığım siteme içerikler atmaya devam ediyorum. Bir süre ara verdikten sonra yavaş yavaş ivme kazanmak adına öncelikle bu içerikte olduğu gibi ufak ufak tüyolar verip ilerleyen aşamalarda daha detaylı ve karmaşık içeriklere adım atacağım. Açıklama ve tanışma faslını sonlandırdıysak anlatıma geçelim.

Öncelikle yapacağımız işlem için ortaya bir senaryo atıp bu senaryo üzerinden anlatımı şekillendirelim. Elimizde bir tane blog sitesi olsun. Blog sitemiz içerisinde içeriklerimize ek olarak bu içeriklere ait etiketlerde ayrı sayfalarda listelensin. Şimdi böyle bir olay gerçekleştiğinde karşımıza şöyle bir yapı çıkıyor.

print_r(Article::all());

print_r(Tag::all());

print_r(Article_Tag::all());

 Not :Article modelim içerikleri barındırıyor. Tag modelim etiketleri barındırıyor. Article_Tag modelim içerikler ile etiketleri bağlamamı sağlıyor.

Yazı -> PHP Üyelik İşlemleri  Etiketler -> PHP dersleri, php üyelik işlemleri,  php auth

Yazı -> PHP Aktivasyon İşlemleri Etiketler -> PHP dersleri, php üyelik işlemleri , php aktivate

Şimdi bu iki yazı ve etiketlerine baktığımızda her ikisinde de aynı etiketlerin yer aldığını görüyoruz. Senaryomuza devam edecek olursak ben bir içeriklerimin görüntülendiği sayfada bu içeriklere benzer içerikleri de görmek istiyorum. Bu benzer içerikleri de aynı etiketler üzerinden yapmak istiyorum. Şimdi içeriklerimize geri dönüp bir tanesini seçelim. 

Yazı -> PHP Üyelik İşlemleri "  bu içeriğimin etiketlerini çektiğimde karşıma " Etiketler -> PHP dersleri, php üyelik işlemleri,  php auth " çıkacaktır.

Ben bu etiketleri explode(parçalayıp) edip " PHP dersleri " , "php üyelik işlemleri" ,  " php auth"  şeklinde tekrar içeriklerimde etiket olarak arattığımda karşıma şöyle bir olay çıkacak.

$r_data = Article_Tag::where('article_id',$article_post->article_id)->get();
$r_id = []; 
$test = json_decode(json_encode($r_data));
foreach ($test as $t_data){
    array_push($r_id,$t_data->tag_id);
}
Article_Tag::whereIn('tag_id',$r_id)->get();

 

Kodumuzda bize gelen içerik ID'sine ait etiketleri Article_Tag modelimizde aratarak verileri $r_data değişkenimize atadık. Gelen verilerimiz Object formatında olduğu için benim kullandığım basit bir yöntemle bu Objecti stabil hale dönüştürdük ve foreach döngüsüyle içerisinde yer alan her etiketin ID'sini $r_id dizisine atadık. Artık bu içeriğe ait etikerlerin neler olduğunu biliyoruz.

Burada kullanmış olduğum whereIn() fonksiyonu sadece belirlenmiş içerikleri filitreler. Örneğin sadece ID'si 1 olanı getir veya sadece ID'si "1,2,3,4" olanları getir. Bizede tam olarak lazım olanda bu son verdiğim örnek.O içeriğe ait etiketleri alıp dizi haline getiriyoruz ve sadece bu etiketlerin ID'lerine ait içeriklerin filitrelenmesini istiyoruz.

" PHP dersleri " =>  Yazı -> PHP Üyelik İşlemleri , Yazı -> PHP Aktivasyon İşlemleri

" php üyelik işlemleri" =>  Yazı -> PHP Üyelik İşlemleri , Yazı -> PHP Aktivasyon İşlemleri

Benim içeriğime ait olan yazıları dışlamak için sorguma "where('article_id','!=',$article_post->article_id)" ekliyorum.

Article_Tag::whereIn('tag_id',$r_id)->where('article_id','!=',$article_post->article_id)->get();

Bu işlemden sonra çıktım şu şekilde olacaktır.

" PHP dersleri " =>  Yazı -> PHP Aktivasyon İşlemleri

" php üyelik işlemleri" => Yazı -> PHP Aktivasyon İşlemleri

Burada asıl problemimiz gün yüzüne çıkmış oluyor. Eğer ben çıktıyı yayınlarsam aynı içeriği iki defa göstermiş olacağım. Bunu engellemek için çok basit bir kod olan ve neredeyse herkesin bildiği bir yönetimi  " SQL Grup " u kullanmamız gerekiyor. Laravel içerisinde bu kodu "groupBy()" fonksiyonuyla rahatlıkla gerçekleştirebiliyoruz. Sonuç olarak kodumuz şu hale dönüşecek ve biz bu uzun uzadıya anlattığım senaryoya bir nokta koyacağız.

Article_Tag::whereIn('tag_id',$r_id)->where('article_id','!=',$article_post->article_id)->groupBy('article_id')->get();

 

Yorum Yap

Mail adresiniz sizinle iletişime geçebilmek amacıyla istenmektedir. Herkese açık bir platformda yayınlanmayacaktır.