我创建了一个搜索功能,用于搜索数据库中所有帖子的名称和内容字段。其中一些帖子是关系密切的(父母和孩子)。我有一个问题,好像我的搜索在子帖子中返回一个命中,我想只返回父数据(以最小化负载)。
我的帖子模型:
public function children()
{
return $this->hasMany('App\Post','parent_post_id','id');
}
public function children_count()
{
return $this->children()
->selectRaw('parent_post_id, count(*) as answers')
->groupBy('parent_post_id');
}
public function parents()
{
return $this->hasOne('App\Post','id','paren_post_id');
}
public function author()
{
return $this->hasOne('App\User', 'id', 'user_id');
}
我的搜索查询:
$posts = Post::with('children')
->with('children_count')
->with('author')
->where('name','like','%'.$search_term.'%')
->orWhere('content','like','%'.$search_term.'%')
->orderBy('created_at','desc')
->groupBy('id')
->paginate(10);
示例:帖子#1有两个孩子,Post#2和Post#3。我的搜索在Post#3中查找数据,现在我希望它返回Post#1的数据。
修改 我知道我需要解释更多我想要实现的目标。
帖子表格结构:
我正在搜索每个帖子的名称和内容字段(作者(user_id)此时无关紧要)。当搜索在子帖子中找到命中时(将parent_post_id设置为父ID),我只想获取父数据(id,slug,name,content等)
我能够通过以下方式实现这一目标:
$posts = DB::table('posts as a')
->leftJoin('posts as b', 'b.parent_post_id', '=', 'a.id')
->where('a.name','like','%'.$search_term.'%')
->orWhere('a.content','like','%'.$search_term.'%')
->orWhere('b.name','like','%'.$search_term.'%')
->orWhere('b.content','like','%'.$search_term.'%')
->select('a.*')->orderBy('a.created_at','desc')->paginate(10)
但是当时无法成功计算所有返回父母的孩子。这也可能会给出一些如何包装这种Laravel方式的想法
有人能指出我正确的方向吗?
答案 0 :(得分:0)
class Post extends Model{
public function children()
{
return $this->hasMany(Post::class, 'parent_post_id', 'id');
}
public function children_count()
{
return $this->children()
->selectRaw('parent_post_id, count(*) as answers')
->groupBy('parent_post_id');
}
public function parents()
{
return $this->hasOne(Post::class, 'id', 'parent_post_id');
}
public function author()
{
return $this->hasOne(User::class, 'id', 'user_id');
}
}
$posts = Post::with(['children_count', 'author', 'children'])
->whereHas('author', function ($query) use ($search_term) {
$query->where('name', 'like', '%' . $search_term . '%');
})
->orWhere('content','like','%' . $search_term . '%')
->orderBy('created_at', 'desc')
->paginate(10);