Laravel 5.2 - 缓存,分页和随机顺序

时间:2016-11-25 11:05:46

标签: json caching pagination eloquent laravel-5.2

我必须在多个页面上显示帖子,但我希望订单始终不同。不幸的是,inRandomOrder()可以通过请求其他页面来提供已显示的项目,orderBy(DB::raw('RAND(aseed)')orderByRaw('RAND(aseed)')(会话常量aseed)是特定于数据库的,并且在大数据集上速度较慢。

我决定缓存包含要显示的帖子的ID的数组,然后将其洗牌并检索它以进行分页。

修补程序中的一个简单示例:

>>>$posts_ids = Post::pluck('id')->shuffle();
=> Illuminate\Support\Collection {#835
 all: [
   8,
   6,
   1,
   2,
   4,
   7,
   3,
   5,
 ],
}


>>>$sliced_ids = $posts_ids->slice(0,2)->all();
=> [
 8,
 6,
]

>>> Post::whereIn('id',$posts_ids->slice(0,2)->all())->get();

=> Illuminate\Database\Eloquent\Collection {#865
 all: [
   App\Post {#883
     id: 6,
     ...
   },
   App\Post {#881
     id: 8,
     ...
   }
 ],
 }

whereIn(也是findMany)方法返回的帖子按升序排列,原因是使用where子句...WHERE id IN (6,8)。一个解决方案可能是orderByRaw('FIELD(id,$sliced_ids),但是 同样适用于orderByRaw('RAND(aseed)') ...

是否有一种有效的方法可以在页面间使用一致的随机顺序进行分页?

编辑:解决方案

我正在探索使用inRandomOrder的可能性,缓存Eloquent Collection并重建它。类似的东西:

 $posts = Cache::remember('posts', 30, function(){ 
     return serialize(Post::with('terms')->inRandomOrder()->get());
 });
 $posts = unserialize($posts);

在这种情况下,我认为最好使用if (Cache::has('key')){...}

修改

我不知道它是否可以依赖于redis连接类型:在tcp上我必须序列化和反序列化,而在unix socket上它可以工作而不需要序列化/反序列化

0 个答案:

没有答案