Laravel 4 - 分页与过滤器雄辩ORM [英] Laravel 4 - paginate with the filter Eloquent ORM

查看:239
本文介绍了Laravel 4 - 分页与过滤器雄辩ORM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想过滤我的ORM请求与2关系多对多:区域和工作。

I want to filter my ORM request with 2 relations many-to-many : Regions and Jobs.

我需要分页,但$ final-> paginate()不可能,但我不知道为什么。

I need paginate, but $final->paginate() is not possible, but i don't know, why.

如何改进我的代码使用 - > paginate()和没有Paginatore :: make

How ameliorated my code for to use ->paginate() and no Paginatore::make

    /* sélectionne tout les candidats qui sont disponnibles, et qui ont une date inférieure
     * à celle configuré
     */
    $contacts = Candidate::with('regions', 'jobs')
                            ->where('imavailable', '1')
                            ->where('dateDisponible', '<=', $inputs['availableDate'])
                            ->get(); // ta requete pour avoir tes contacts, ou par exemple tu fais un tri normal sur tes regions. Il te reste à trier tes jobs.

    // ajoute un filtre, pour n'afficher que ceux qui reponde true aux 2 test dans les foreachs 
    $final = $contacts->filter(function($contact) use($inputs) {

        // par défaut ils sont false
        $isJob = false;
        $isRegion = false;

       // test que le candidat à l'un des jobs recherché par l'entreprise
       foreach($contact->jobs as $job) {

            // si le job id du candidat est dans la liste, alors on retourne true
            if(in_array($job->id, $inputs['job'])) {

               $isJob = true;
            }
       }
       // test que le candidat accepte de travailler dans l'une des régions echerchées
       foreach($contact->regions as $region) {

            // si region id du candidat est dans la liste, alors on retourne true
            if(in_array($region->id, $inputs['region'])) {

               $isRegion = true;
            }
       }

       // si les 2 renvoie true, alors nous returnons le candidat à la vue
       if($isRegion && $isJob){

            return true;
       }
       else{

            return false;
       }
    });

    // converti le resultat en tableau pour l'importer dans le Paginator
    $finalArray = $final->toArray();

    // calcule le nombre de candidat dans le tableau
    $finalCount = count($finalArray);

    // créer le pagniate manuellement, car on ne peux faire $final->paginate(20)
    $paginator = Paginator::make($finalArray, $finalCount, 2);

    // return la liste des candidats
    return $paginator;

谢谢。

推荐答案

好的,第三次是魅力:

首先,你的性能问题来自数据库结构,而不是查询

First, your performance problem comes from the database structure, not the query.

您需要添加以下索引才能提升效能:

You need to add the following indexes to get a serious performance boost:

ALTER TABLE  `candidate_region` ADD INDEX  `REGION_ID` (  `region_id` )
ALTER TABLE  `candidate_region` ADD INDEX  `CANDIDATE_ID` (  `candidate_id` )
ALTER TABLE  `candidate_job` ADD INDEX  `JOB_ID` (  `job_id` )
ALTER TABLE  `candidate_job` ADD INDEX  `CANDIDATE_ID` (  `candidate_id` )

具有适当索引的数据透视表工作更好。

Pivot tables with the proper indexes work better.

第二个,这是您要运行的(纯)SQL查询:

Second, THIS is the (pure) SQL query you want to run:

SELECT * 
FROM candidates 
INNER JOIN candidate_region
ON candidates.id = candidate_region.candidate_id
INNER JOIN candidate_job
ON candidates.id = candidate_job.candidate_id
WHERE imavailable = 1 AND dateDisponible <= '2013-12-31' AND region_id IN (2,3,4,43,42) AND job_id IN (1,2,5,8)

使用上面的索引,此查询运行在第二个。没有索引,它在我的机器上超时。

With the indexes above, this query runs under a second. Without the indexes, it timed out on my machine.

第三个,这是这个查询在Fluent中应该是这样的:

Third, this is what this query should look like in Fluent:

DB::table('candidates')
  ->join('candidate_region', 'candidates.id', '=', 'candidate_region.candidate_id'); 
  ->join('candidate_job', 'candidates.id', '=', 'candidate_job.candidate_id'); 
  ->whereIn('candidate_region.region_id',$inputs['region'])
  ->whereIn('candidate_job.job_id',$inputs['job'])
  ->where('imavailable', '1')
  ->where('dateDisponible', '<=', $inputs['availableDate'])
  ->get(); // Or paginate()

这是未经测试的,但应按原样或稍微修改。

This is untested, but should work as-is or with minor modifications.

享受!

这篇关于Laravel 4 - 分页与过滤器雄辩ORM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆