У меня есть интерфейс, который отображает список сообществ на платформе.В сообществах есть участники, и, в свою очередь, участники / профили могут дружить друг с другом.На странице листинга каждая общая карта должна отображать количество участников (в сообществе) и количество друзей (друзей в профиле) из этих участников.
Вот иллюстрация того, как выглядит общая карта

Сначала я получаю сообщества с участниками:
$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();
});
-Community_members миграция
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();
});