Laravel雄辩地计算了一种关系

Arc*_*ade 28 php laravel eloquent

我是laravel和eloquent的新手,我不确定这是否可能.但是我有2张桌子,有一对多的关系.一个是"位置",一个是"用户".一个位置可以有很多用户.

因此,如果我希望获得所有用户的所有位置,我会这样做:

Location::with("users")->get();
Run Code Online (Sandbox Code Playgroud)

但我也想知道每个位置有多少用户,我试过这样做

Location::with("users")->count("users")->get();
Run Code Online (Sandbox Code Playgroud)

但那没用.

ben*_*ill 36

如果您使用预先加载,则不会出现提及的n + 1问题.

$locations = Location::with('users')->get();

$locations->users()->count();
Run Code Online (Sandbox Code Playgroud)

无论您有多少用户或位置,这都会产生三个查询.

  • 计算针对位置模型的查询
  • 从位置选择*
  • 从中的用户中选择*

混淆起因于这也有效:

$locations = Location::all();

$locations->users()->count();
Run Code Online (Sandbox Code Playgroud)

但在这种情况下,它会针对每个位置进行一次查询.

有关详细信息,请参阅文档:http: //laravel.com/docs/eloquent#eager-loading

  • 虽然很晚才到派对,但是想指出你仍然会遇到n + 1问题.你需要在foreach中使用`$ location> users-> count()`,基本上不要访问方法users(),而是访问属性,或者每次都进行查询. (10认同)

Bog*_*dan 12

您应该使用 justwithCount但我想它在 2012 年不可用。

所以它应该是这样的:

Location::with("users")->withCount("users")->get();
Run Code Online (Sandbox Code Playgroud)

并且您将拥有一个users_count可用于您的对象的属性。

阅读文档以获取更多详细信息:https : //laravel.com/docs/5.5/eloquent-relationships#querying-relations(向下滚动一点,您将看到Counting Related Models

  • 您可以使用“withCount()”而不使用“with()”。 (2认同)

iTe*_*ech 7

您需要在每个位置记录上调用count方法以获取每个位置的用户数,这是一个示例:

foreach(Location::get() as $location) // or foreach(Location::with("users")->get() as $location)
{
  echo $location->users()->count();
}
Run Code Online (Sandbox Code Playgroud)

这应该可以解决您的问题,并为您提供每个位置的用户数量.您可以在循环中添加一个检查以忽略用户count = 0的位置

  • 这是不好的.它导致[n + 1查询问题](http://stackoverflow.com/questions/97197/what-is-the-n1-selects-issue?lq=1) (32认同)
  • 这会使用与Location :: get()的结果一样多的数据库查询吗? (6认同)