有效地将查询转换为预期的数组 - Laravel
Posted
技术标签:
【中文标题】有效地将查询转换为预期的数组 - Laravel【英文标题】:Convert queries to expected array efficiently - Laravel 【发布时间】:2021-04-10 20:13:31 【问题描述】:我有一个dictionaries
表,如下所示:
这是我想要的数组结果:
我已经通过这些丑陋的代码实现了结果:
$dictionaries = Dictionary::all();
$carriers_array = [];
$carriers = $dictionaries->unique('Carrier');
foreach($carriers as $carrier)
$carriers_array[] = $carrier->Carrier;
$DOM_INLs_array = [];
foreach($carriers_array as $carrier_item)
$DOM_INLs = $dictionaries->where('Carrier', $carrier_item)->unique('DOM_INL');
foreach($DOM_INLs as $DOM_INL)
$DOM_INLs_array[$carrier_item][] = $DOM_INL->DOM_INL;
$groups_array = [];
foreach($DOM_INLs_array as $carrier => $DOM_INLs)
foreach($DOM_INLs as $DOM_INL)
$groups = $dictionaries->where('Carrier', $carrier)->where('DOM_INL', $DOM_INL)->unique('Group');
foreach($groups as $group)
$groups_array[$carrier][$DOM_INL][] = $group->Group;
$routes_array = [];
foreach($groups_array as $carrier => $DOM_INLs)
foreach($DOM_INLs as $DOM_INL => $groups)
foreach($groups as $group)
$routes = $dictionaries->where('Carrier', $carrier)->where('DOM_INL', $DOM_INL)->where('Group', $group)->unique('Route');
foreach($routes as $route)
$routes_array[$carrier][$DOM_INL][$group][] = $route->Route;
$sectors_array = [];
foreach($routes_array as $carrier => $DOM_INLs)
foreach($DOM_INLs as $DOM_INL => $groups)
foreach($groups as $group => $routes)
foreach($routes as $route)
$sectors = $dictionaries->where('Carrier', $carrier)->where('DOM_INL', $DOM_INL)->where('Group', $group)->where('Route', $route)->unique('Sector');
foreach($sectors as $sector)
$sectors_array[$carrier][$DOM_INL][$group][$route][] = $sector->Sector;
dd($sectors_array);
但是它运行得很慢,我想要另一种方法来获得相同的结果但更有效。有人可以帮忙吗?
【问题讨论】:
请编辑您的问题并包括您的查询。 @AhmadKarimi 我更新了包含$dictionaries
查询的问题
【参考方案1】:
这看起来像是一堆嵌套的 map
s 和 groupBy
s,最后是 pluck
:
箭头函数,php 7.4+:
$dictionaries->groupBy('Carrier')
->map(fn ($i) => $i->groupBy('DOM_INL')
->map(fn ($i) => $i->groupBy('Group')
->map(fn ($i) => $i->groupBy('Route')
->map->pluck('Sector')
)
)
);
使用匿名函数:
$dictionaries->groupBy('Carrier')->map(function ($i)
return $i->groupBy('DOM_INL')->map(function ($i)
return $i->groupBy('Group')->map(function ($i)
return $i->groupBy('Route')->map->pluck('Sector');
);
);
);
如果您只需要以这种方式分组的这些结果并且不需要叶子只是“部门”值,这将是 1 次调用 groupBy
:
$dictionary->groupBy(['Carrier', 'DOM_INL', 'Group', 'Route'])
【讨论】:
您的解决方案看起来很有希望,但是这些代码看起来像是新版本的php,能否给我与旧php版本兼容的代码? 当然,检查更新,看看是否适合你 我刚刚遇到了另一个问题。也就是说,要获取当前结果,我必须查询整个表并将所有结果加载到内存中。如果表只有 10,000 行,我不会有问题。但是,如果表有 10 万行、20 万行或更多……每个查询将占用 1GB 或更多的内存,导致服务器死亡。我用的VPS只有2GB内存……你有办法帮我解决内存使用问题,还能得到和现在一样的结果吗?以上是关于有效地将查询转换为预期的数组 - Laravel的主要内容,如果未能解决你的问题,请参考以下文章
有效地将不均匀的列表列表转换为用 nan 填充的最小包含数组