laravel - 获取包含 10 个项目的缓存 Eloquent 集合超时
问题描述
我正在构建一个搜索功能,它返回使用 LengthAwarePaginator 分页的大型集合。我正在尝试使用一个名为 $searchFilter_$query_$offsetPages 的键来缓存结果,以获取单页返回的结果(10 项)。它进入缓存就好了。但是,当我尝试使用 Cache::has($key) 检查或使用 Cache::get($key) 获取时,它会超时。
同样的问题也出现在浏览器和工匠 Tinker 中。奇怪的是,当我将一组随机的 10 个项目放入 Tinker 的缓存中并将它们取回时,一切正常。我使用 Redis 作为缓存驱动程序。
这是我的控制器方法:
public function search($filter, $query, $layout, Request $request) {
if($layout == "list-map") {
return view("list-map")->with(['filter' => $filter, 'query' => $query, 'layout' => 'list-map']);
} else {
$offsetPages = $request->input('page', 1) - 1;
$cacheKey = $filter . "_" . $query . "_" . $offsetPages;
if(Cache::has($cacheKey)) {
\Log::info("fetching results from cache");
$data = Cache::get($cacheKey);
$totalCt = $data[0];
$results = $data[1];
} else {
$results = $this->getResults($filter, $query);
$totalCt = $results->count();
$results = $results->slice($offsetPages, $this->resultsPerPage);
\Log::info("caching results");
Cache::put($cacheKey, [$totalCt, $results], 5);
}
$results = new LengthAwarePaginator($results,
$totalCt,
$this->resultsPerPage,
$request->input('page', 1),
['path' => LengthAwarePaginator::resolveCurrentPath()]
);
return view($layout)->with(['filter' => $filter, 'query' => $query, 'layout' => $layout, 'results' => $results]);
}
}
解决方案
因此,问题在于从我的 getResults() 方法返回的集合中的许多模型都是通过关系查询获得的。当我在 10 个结果的单页上 dd($results) 时,我可以看到每个模型上都有一个“关系”字段。在该数组中,有数千个基于我最初查询的关系的递归相关模型。我找不到有关不急于加载这些相关模型的选项的任何信息。相反,我想出了一些 hacky 解决方法来直接获取模型:
$results = $results->slice($offsetPages, $this->resultsPerPage);
//load models directly so they don't include related models.
$temp = new \Illuminate\Database\Eloquent\Collection;
foreach($results as $result) {
if(get_class($result) == "App\Doctor") {
$result = Doctor::find($result->id);
} else if(get_class($result == "App\Organization")) {
$result = Organization::find($result->id);
}
$temp->push($result);
}
$results = $temp;
\Log::info("caching results");
Cache::put($cacheKey, [$totalCt, $results], 5);
如果有人知道在这种情况下的最佳做法,请告诉我。谢谢!
编辑:我找到了一个更好的解决方案,而不是上述解决方法。如果我像这样查询我的关系:$taxonomy->doctors()->get() 而不是 $taxonomy->doctors,它不会加载到巨大的递归关系中。
推荐阅读
- javascript - 当我单击它们时,如何使用 Javascript 使圆圈改变颜色?另外,如果所有圆圈都是红色的,如何使文本出现?我
- serilog - 检测损坏的日志接收器的最佳实践
- javascript - 如何使用 joi 设置正确的模式和验证?
- c++ - 如何创建一个将学生姓名与其分数相匹配的数组?
- python - 如何将 'features="html.parser"' 添加到 BeautifulSoup 构造函数
- reactjs - 将使用 create react app 创建的 react 应用程序移动到另一台计算机
- php - 如何在html表格中显示选择框?
- java - 缓存其他实体映射的关系
- node.js - 使用 SQS 私有端点批量发送消息
- flask - 烧瓶中的 sqlalchemy.exc.OperationalError