我有一个界面,该界面显示平台上的社区列表。社区有成员,成员/个人资料可以彼此成为朋友。在列表页面上,每个社区卡都需要显示成员数量(在社区中)以及这些成员中的朋友数量(已登录个人资料的朋友)。
这是一张社区卡的样子的说明
我首先要与成员建立社区:
$communities = $loggedInProfile->communities->load('members')->take(15);
然后遍历社区,然后遍历成员,以找出哪些人与登录用户是朋友。
foreach ($communities as $key => $community) {
$friends = [];
foreach ($community->members as $member) {
if ($loggedInProfile->isFriendWith($member)) {
array_push($friends, $member);
}
}
$community->members_who_are_friends = $friends;
}
我的问题是,当关联变大时,就查询数量而言这非常麻烦。是否有更好的方法来检索这些关系而不必使用嵌套的for循环?我也在用Elasticsearch索引所有数据。用Elasticsearch这样的检索会更好吗?这对于hasThrough
来说是个好用例吗?
更新
members
关系:
public function members()
{
return $this->belongsToMany('App\Profile', 'community_members', 'community_id', 'profile_id')->withTimestamps();
}
isFriendWith
关系:
public function isFriendWith(Model $recipient)
{
return $this->findFriendship($recipient)->where('status', Status::ACCEPTED)->exists();
}
检查是在名为friendships
的表上完成的。检查status
列(可以为0或1)以查看是否为好友。
findFriendship
支票:
private function findFriendship(Model $recipient)
{
return Friendship::betweenModels($this, $recipient);
}
数据库结构:
-个人资料迁移
Schema::create('profiles', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
});
-社区迁移(外键是社区的owner
)
Schema::create('communities', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('profile_id');
$table->foreign('profile_id')->references('id')->on('profiles');
$table->string('slug')->unique();
});
-社区成员迁移
Schema::create('community_members', function (Blueprint $table) {
$table->primary(['profile_id', 'community_id']);
$table->unsignedInteger('profile_id');
$table->foreign('profile_id')->references('id')->on('profiles');
$table->unsignedInteger('community_id');
$table->foreign('community_id')->references('id')->on('communities');
$table->timestamps();
});
-友谊迁移
Schema::create('friendships'), function (Blueprint $table) {
$table->increments('id');
$table->morphs('sender');
$table->morphs('recipient');
$table->tinyInteger('status')->default(0);
$table->timestamps();
});
答案 0 :(得分:0)
在您的行中:
$communities = $loggedInProfile->communities->load('members')->take(15);
load()
用于执行Lazy Eager加载,即您在检索社区后加载成员,从而为每个社区产生不同的查询。您可以使用with()
通过单个查询提取全部数据。另外,take(15)
是对结果集合执行的,而不是对查询执行的。试试这个:
$communities = $loggedInProfile->communities()->with('members')->take(15)->get();