How could I cache every api response results in my query in Laravel?

柔情痞子 提交于 2020-01-24 19:31:17

问题


I got a bunch of data in my tables and I want everytime a user enters a keyword to search it will be cached in order for the next user who has a similar input to the previous user to get a faster results. I read the docs about caching it they only cover with selecting all the database without some $request params in it. How could I do that? I am using querybuilder btw. Here is my original code

  public function getRecordDetails(Request $request){
        if(!empty($request->limit)){
            $limit = " LIMIT ".$_REQUEST['limit'];
        }
        else{
            $limit= '';
        }
        if(empty($request->projectname)){
            dd('Field is empty');
        }
        else{
            $result =  DB::connection('mysql2')
                    ->table('xp_pn_ura_transactions')
                    ->whereRaw(DB::raw("CONCAT(block, ' ', street,' ',project_name,' ',postal_code,'')LIKE '%$request->projectname%' order by STR_TO_DATE(sale_date, '%d-%M-%Y') desc"))
                    ->limit($request->limit)
                    ->distinct()
                    ->get();
            $count =  DB::connection('mysql2')
                    ->table('xp_pn_ura_transactions')
                    ->whereRaw(DB::raw("CONCAT(block, ' ', street,' ',project_name,' ', postal_code,'')LIKE '%$request->projectname%'"))
                    ->count();
            return \Response::json(array(
                'total_count' => $count,
                'result' => $result,
            ));
        }
    }

I got a response like this if i search

 "total_count": 20144,
    "result": [
        {
            "transtype": "RESI",
            "project_name": "WATERFRONT WAVES",
            "unitname": "06-21 ",
            "block": "766",
            "street": "Bedok Reservoir Road  ",
            "level": "06",
         }
    ]

I tried running a query with a cache in it but it gets me an error of undefined variable request but when i put request to it it says Too few arguments to function App\Http\Controllers\PropertySearchController::App\Http\Controllers\{closure}

Here is my final code

  if(!empty($request->limit)){
            $limit = " LIMIT ".$_REQUEST['limit'];
        }
        else{
            $limit= '';
        }
        if(empty($request->projectname)){
            dd('Field is empty');
        }
        else{
            $data = Cache::rememberForever('result', function (Request $request) {
                $result =  DB::connection('mysql2')
                    ->table('xp_pn_ura_transactions')
                    ->whereRaw(DB::raw("CONCAT(block, ' ', street,' ',project_name,' ', postal_code,'')LIKE '%$request->projectname%' order by STR_TO_DATE(sale_date, '%d-%M-%Y') desc"))
                    ->limit($request->limit)
                    ->distinct()
                    ->get();
                $count =  DB::connection('mysql2')
                    ->table('xp_pn_ura_transactions')
                    ->whereRaw(DB::raw("CONCAT(block, ' ', street,' ',project_name,' ', postal_code,'')LIKE '%$request->projectname%'"))
                    ->count();
            });

            return response()->json($data);


            // return \Response::json(array(
            //     'total_count' => $count,
            //     'result' => $result,
            // ));

Also can i get the same json format that is in my previous result? because i observed that the response i returned is not formatted in array which is the $data from cache.


回答1:


You must add use to use the request in your params. Its like this:

$data = Cache::rememberForever('results', function () use($request) {

                $result =  DB::connection('mysql2')
                ->table('xp_pn_ura_transactions')
                ->whereRaw(DB::raw("CONCAT(block, ' ', street,' ',project_name,' ', postal_code,'')LIKE '%$request->projectname%' order by STR_TO_DATE(sale_date, '%d-%M-%Y') desc"))
                ->limit($request->limit)
                ->distinct()
                ->get();

                $count =  DB::connection('mysql2')
                ->table('xp_pn_ura_transactions')
                ->whereRaw(DB::raw("CONCAT(block, ' ', street,' ',project_name,' ', postal_code,'')LIKE '%$request->projectname%'"))
                ->count();

                return json_encode(array('count'=>$count,'result'=>$result));
            });
            return $data;

Put this inside the else statement and it should work but I discovered a problem in this. Because in every request the results will be the same because it is cached the previous request params. For example. If i search a it will output a but when I search b it will still output a because it will execute the previous cache key with the request params. I dont know yet how to change the the cache everytime the user got a different search keyword or request

EDIT

I asked the same question and I found a solution, I know why it is always showing the result it is because your key which is results is the same every time you hit the query. You must add this line of code and replace the results into the dynamic key you instantiate

$key = "results:".$request->projectname.':' $request->limit;
$data = Cache::rememberForever($key , function () use($request){
//query here ........
}


来源:https://stackoverflow.com/questions/59817523/how-could-i-cache-every-api-response-results-in-my-query-in-laravel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!