我有{{1>}模型 belongsToMany Group
,Contacts
belongsToMany Contact
,通常一个群组可以包含大约300,000个联系人,一个联系人可以属于2个或3个群组,我想要一个功能来检索多个给定群组中的所有“唯一”联系人,所以我试过
Groups
它有效,但问题是我发现sql生成的用途是$contacts = Contact::With(array('groups'=>function($query) use ($groups)
{
$query->whereIn('groups.id' , $groups);
}
))->get();
。因此,如果我正在检索100,000个联系人,那么where where in子句中将有100,000个联系人ID。
然后我最终使用了这个
contact_id IN ( ALL CONTACTS' IDs)
但我仍然关注表现。我不知道列表是如何工作的,如果对包含数十万个电子邮件字符串的数组foreach($groups as $group)
{
$contacts = array_unique(array_merge($contacts , $group->contacts()->lists('email'))) ;
}
和array_unique
是个好主意?
答案 0 :(得分:0)
你说:
通常一个小组可以包含大约300,000个联系人和一个联系人 可能属于2或3组
根据这一点,您的关系应为many-to-many,Group
和Contact
都应使用belongsToMany
使用数据透视表contact_group
建立关系:
// Group model
public function contacts()
{
return $this->belongsToMany('Contact');
}
// Contact model
public function groups()
{
return $this->belongsToMany('Group');
}
contact_group
数据透视表可能是这样的:
id | group_id | contact_id
如果你有这样的设置,那么你将能够做到这一点:
$groups = Group::has('contacts')
->with('contacts')
->whereIn('id', [1,2,3]) // group ids, could be any field
->get();
$uniqueContacts = $groups->map(function($group) {
return $group->contacts->lists('email');
})->flatten()->toBase()->unique();
// You got all unique contacts in $uniqueContacts
dd($uniqueContacts); // all unique contacts
不知道它对100,000
个联系人有多快,但应该更好。
更新:加入DB
表并从DB
范围查询,可能是其他(可能更好)的方法。