2017-08-15 68 views
3

我有4个表是在数据库和模型的关系如下:使用约束进行预先加载会产生太多查询。我怎样才能减轻这一点?

Users (hasMany(communities), hasMany(comments), hasMany(submissions)) 
Communities (belongsTo(user), hasMany(submissions)) 
Submissions (belongsTo(community), belongsTo(user), hasMany(comments)) 
Comments (belongsTo(user) , belongsTo(submission)) 

现在。如果我使用的关系得到的,说25所最新提交的,就像这样:

$submissions = Submission::simplePaginate(25); 

我见了运行,通过使用结果的foreach循环后76个查询。

如果我使用预先加载具有以下

$submissions = Submission::with(['user', 'community', 'comments'])->simplePaginate(25); 

我会见了4个查询这是最佳的(我认为)。

现在,我的问题是,在社区中,我有一个名为active的数据库字段,它接受活动社区的1和非活动的0。正如您可能猜到的那样,先前的查询会返回所有内容,包括非活动的社区。

我想到了预先加载的限制,所以我用了以下内容:

$submissions = Submission::with([ 
     'community' => function($query) { 
     $query->active(); 
     } 
    ] 
)->with(['user', 'comments'])->simplePaginate(25); 

这仍然与4次的查询工作,但现在我遇到了另一个问题。此方法过滤不活动的社区,但仍然加载帖子,用户和评论。现在我得到的结果是我从非活动社区获得帖子。

最后,我试过了,在阅读这个社会,以下:

$submissions = Submission::whereHas(
    'community', function($query) { 
     $query->active(); 
    } 
)->with(['user', 'comments'])->simplePaginate(20); 

因此,而不是使用 - >与()我用 - > whereHas()作为有人建议。然而,尽管这会产生正确的结果,也就是说,它仅为来自活动社区的帖子,评论和用户提供了支持,但现在按照我从Laravel Debugbar获得的反馈,它可以在23个查询中执行此操作。

这是正常的吗?这是唯一可以通过Eloquent做到这一点的方法,并且不需要使用连接编写自定义查询?我是否按比例吹出23个查询?

任何帮助将不胜感激。

+0

你说你用( - )替换了' - > whereHas()',但是你提出的代码同时使用...你仍然在寻找23个查询吗? – KST

+0

你的问题是'active()'作用域正在为你得到的每个社区运行一个查询。 – Asur

回答

1

你的问题是,active()范围运行您检索每一个社区的查询,在您的案件20

优化这个你可以做的Submission模型的特定关系,你过滤活跃的社区主动。现在

// Submission model 

public function activeCommunities(){ 

    return $this->hasMany(Community::class)->whereActive(true); 
} 

您的查询看起来像:

$submissions = Submission::with(['user', 'comments', 'activeCommunities]) 
    ->simplePaginate(25); 

这应执行4个查询我相信。

希望这可以帮助你。

+0

尽管您的答案很有意义,但尝试它时仍会产生28个查询。我使用的代码如下 为模型,和 '$ submissions = Submission :: with(['user','filtered']) - > withCount('comments') - > simplePaginate(25) ;' –

+0

@GeorgeChatzipavlou如果你可以用你正在查询的查询来编辑你的文章,这将是非常有用的,所以我可以知道他们来自哪里。让我知道你什么时候完成的。 – Asur

0

所以,经过一段时间的修补之后,我找到了一个解决方案,但我仍然不确定。我发布这个以供将来参考,因为它解决了我的问题。我使用的代码如下

$submissions = Submission::whereHas(
     'community', function($query) { 
     $query->where('is_active', true); 
     } 
    )->with(['user', 'community'])->withCount('comments') 
    ->paginate(25); 

所以,我尝试使用whereHas()检查之前实际渴望的车型存在加载community模型,如果是有道理的?它似乎让我得到我想要的结果,因为我现在执行总共4个查询来获取所有提交的内容以及相关信息,过滤不活动的社区。

相关问题