Laravel tag search to return images that contain all tags

前端 未结 2 1908
萌比男神i
萌比男神i 2021-01-03 12:09

I\'m developing an application that lists images, and has multiple tags assigned to each image. I\'d like to be able to find the images that are tagged with all

相关标签:
2条回答
  • 2021-01-03 12:30

    Looking for images that has all the tags, we will probably need to count our results and group by the image_url after making our necessary joins. This way, we can see how many tags each image matches and just get the images that match all the tags using the count because we know how many tags we have.

    $tags = explode(' ', $tag_text);
    
     $images = DB::table('images')
      ->select(DB::raw('COUNT(*) AS `TheCount`, images.download_url'))
      ->join('image_tag', 'images.id', '=', 'image_tag.image_id')
      ->join('tags', 'tags.id', '=', 'image_tag.tag_id')
      ->whereIn('tags.id', $tags)
      ->groupBy('images.download_url')
      ->having('TheCount', count($tags))
      ->get();
    

    If you need more than just the download_url for each image, you might need to change it up a bit. I'd suggest instead of selecting and grouping by download_url, do it by the image's id and then you can set it up as a subselect and join it back up with the images table on the matching id's if that makes any sense.

    Or just use ->lists('images.id') to get the array of id's and make another query on the images table getting all images in that list of id's.

    0 讨论(0)
  • 2021-01-03 12:41

    Manual count and having would work, but you can use simple whereHas instead:

    // let it be array of tag ids:
    $tagsIds;
    
    $images = Image::whereHas('tags', function ($q) use ($tagsIds) {
       $q->whereIn('tags.id', $tagsIds);
    }, '=', count($tagsIds))->get();
    

    However mind that both mine and @user3158900's solutions will work only, when you have no duplicates on the pivot table. Using Eloquent's attach method on BelongsToMany relation may lead to such situation.

    0 讨论(0)
提交回复
热议问题