Laravel Model 中附加的字段如何使用排序和分页功能?

class Server extends Model
{
    protected $table = 'servers';
    protected $primaryKey = 'server_id';
    protected $appends = ['online'];

    public function getOnlineAttribute()
    {
        $redis = Redis::connection('db0');
        if ($redis->hexists('entrance_online', $this->server_id)) {
            return $redis->hget('entrance_online', $this->server_id);
        } else {
            return 0;
        }
    }
}

如上面的代码所示,一个模型类对应mysql的一张表,表中已有的字段可以使用mysql的排序功能,laravel已封装好;模型中有一个online字段是附加上去的,表示这台服务器当前在线的人数,因为online数据会经常变动,所以把数据存放在了redis中,那么在使用的时候如何根据online字段进行排序和分页?

我的思路是先把servers表中的数据从mysql全读出来,然后使用PHP的数组函数进行排序,再然后对上一步的数据进行array_chunk分块,根据页码返回对应区块的数据,但感觉这样做不够优雅,数据量大的时候会出现内存不够或者性能问题。

社区的各路精英,有没有更优雅的解决办法呢?

cosyphp
抄底斗罗
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
最佳答案

可以考虑先从 redis 中取出已排序的 server_id, 然后再从查 mysql

5年前 评论
讨论数量: 7
你看我吊吗啊

不好意思,真没在model层做过排序。。不知道能不能实现你的需求

5年前 评论

个人建议使用集合的形式进行处理;比如使用集合的 forPage()、sortBy()等处理。。

5年前 评论

查询完数据后 用集合的排序就好了

5年前 评论

这样只能一次性把所有的数据取出来,然后在内存中使用集合分页。

  • 先注册一个宏
    AppServiceProvider@register 中,写上如下代码:

    Collection::macro('paginate', function ($perPage, $total = null, $page = null, $pageName = 'page') {
            $page = $page ?: LengthAwarePaginator::resolveCurrentPage($pageName);
            return new LengthAwarePaginator(
                $this->forPage($page, $perPage),
                $total ?: $this->count(),
                $perPage,
                $page,
                [
                    'path' => LengthAwarePaginator::resolveCurrentPath(),
                    'pageName' => $pageName,
                ]
            );
        });
  • 在控制器就可以这样分页

    Account::all()->sort('XXX')->paginate(5);
5年前 评论

@青风百里 这里的orderBy()好像不生效
补充一个:


Collection::macro('orderBy', function ($column,$type='desc') {
       return collect($this->items)
              ->when($type,function ($query) use($column,$type) {
                    if ($type == 'asc') {
                        return $query->sortBy($column);
                    }
                    return $query->sortByDesc($column);
                })
              ->values();
 });
5年前 评论

@qinguanglong 我写错了,集合里的排序是 sort()

5年前 评论
romp 5年前

可以考虑先从 redis 中取出已排序的 server_id, 然后再从查 mysql

5年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!