dvy*_*yio 1 join query-builder laravel eloquent laravel-4
我正在开发一个列出图像的应用程序,并为每个图像分配了多个标签.我希望能够找到标记有所搜索的所有标签的图像.
images 表- id
- download_url
- image_width
- image_height
Run Code Online (Sandbox Code Playgroud)
tags 表- id
- name
Run Code Online (Sandbox Code Playgroud)
image_tag 表- id
- image_id
- tag_id
Run Code Online (Sandbox Code Playgroud)
在我的模型中Image,我已经得到了belongsToMany('Tag'),并且在我的模型中Tags,我得到了belongsToMany('Image').到目前为止,这一切都按照我的希望进行.
但是,当我尝试通过标签搜索图像时,会出现问题.我似乎能够使用以下代码进行搜索或搜索.
$tags = explode(' ', $tag_text);
$query = DB::table('images');
$query->join('image_tag', 'images.id', '=', 'image_tag.image_id');
$query->join('tags', 'tags.id', '=', 'image_tag.tag_id');
foreach ($tags as $tag)
{
$query->orWhere('tags.name', '=', $tag);
}
$result = $query->get();
Run Code Online (Sandbox Code Playgroud)
如果我搜索(例如)nyc skyscraper,我会得到一个包含标签nyc或标签摩天大楼的图像列表.但是,我只想显示带有标签nyc和标签摩天大楼的图像.
我尝试$query->orWhere('tags.name', '=', $tag);改为$query->where('tags.name', '=', $tag);,但那不会返回任何结果(大概是因为它弄乱了标签名称搜索).查询Laravel正在运行"select * from 'images' inner join 'image_tag' on 'images'.'id' = 'image_tag'.'image_id' inner join 'tags' on 'tags'.'id' = 'image_tag'.'tag_id' where 'tags'.'name' = ? and 'tags'.'name' = ?"绑定nyc和skyscraper.
我想知道单独对每个标签进行图像搜索(在上面的例子中将返回带有标签nyc的图像然后返回标签摩天大楼的图像),然后选出两个结果中出现的图像,但我不是确定实现这一目标的最佳方式是什么,以及它是否是最有效的方式.
我怀疑使用我目前缺少的查询构建器有一种简单的方法可以做到这一点!
让它变得更复杂(当前不起作用)的是,除了标签搜索之外,我还想用(例如)一定宽度来显示图像.所以在标记代码之后,我已经包含了
$query->where('image_width', '>', 1000);
Run Code Online (Sandbox Code Playgroud)
返回宽度超过1000像素的所有图像,但仅当我不包含标记搜索代码时.如果我包含标签搜索代码,它将忽略搜索的图像宽度部分.
因此,理想情况下,我想要返回标记为nyc且标记为摩天大楼的图像,并且宽度超过1000像素.
手动计数并having可以工作,但您可以使用简单的whereHas代替:
// let it be array of tag ids:
$tagsIds;
$images = Image::whereHas('tags', function ($q) use ($tagsIds) {
$q->whereIn('tags.id', $tagsIds);
}, '=', count($tagsIds))->get();
Run Code Online (Sandbox Code Playgroud)
但是请注意,当您在数据透视表上没有重复项时,我和@ user3158900的解决方案都将起作用.attach在BelongsToMany关系上使用Eloquent的方法可能会导致这种情况.