Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

how to simplify this complex query

This is an extract of one of my php functions. I’m struggling to get this optimized as is super slow, as I need to load all interview records, and then check if the current user is either assigned as user_id on the interview record, or if the user->id is in the interviews shared_user_ids which is json

$interviews___ = interviews::whereIn('archived', [0, false, null])->sortBy('created_at')->reverse();
        $interviews__ = [];
        foreach($interviews___ as $in){
            $sameUser = $in->user_id == $user->id; // this line to...
            $ids_ = json_decode($in->shared_user_ids, true);
            $ids = [];
            foreach($ids_ as $id){
                $ids[] = (int)($id);
            }
            $containsUser = in_array($user->id, $ids);  // ...to this line
            if($sameUser || $containsUser){
                $interviews__[] = [
                    "id"=>$in->id,
                    "title"=>$in->title,
                    "created" => $in->created_at,                
                    "open_rate" => $in->getOpenRates(),
                    'total_leads' => $in->getLeads(),
                    'newOpensCounter' => $in->getNewOpens(),
                    'openDiff' => $in->getOpenDiff(),
                    'interview_count' => $in->getInterviewCount(),
                    'sent_count' => $in->getCount(),
                    'sent_count_marketing' => $in->getCountMarketing(),
                    'sent_count_vlog' => $in->sent_count_vlog,
                    'openedInterview' => $in->openedInterview ?? 0,
                    'openedBespoke' => $in->openedBespoke ?? 0,
                    'openedMarketing' => $in->openedMarketing ?? 0,
                    'openedVlog' => $in->openedVlog ?? 0,
                    'archived' => $in->archived
                ];
            }
        }

I’m also using PostgreSQL

Edit – expected result

somehow create a sql query which does the user id checks for the user_id and the shared_user_id

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

then return only those which match the requirements

  1. archived has a value of (0, false, null) <- required
  2. user_id matches user->id [optional]
  3. user->id in shared_user_ids [optional]

>Solution :

You should be able to query the columns in the interview query itself. You can read more about querying JSON columns here.

You should also change the sortBy to orderBy since sortBy can only be used on collections.

$interviews___ = interviews::whereIn('archived', [0, false, null])
    ->where(function($query) {
        $query->whereJsonContains('shared_user_ids', $user->id)
            ->orWhere('user_id', $user->id);
    })
    ->orderBy('created_at', 'DESC')
    ->get();
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading