CodeIgniter Forums

Full Version: Codeigniter 4 Model Aggregation
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
mogoosse library is support  Aggregation  and l Aggregate Pagination  ci4  base model needs this    Aggregation
this   mogoosse  inerface for   Aggregate
Code:
export interface AggregatePipeLine {
  $sort?: object;
  $project?: object | any;
  $match?: object | any;
  $group?: object;
  $limit?: number;
  $page?: number;
  $skip?: number;
  $unwind?: string;
  $replaceRoot?: object | any;
  $addFields?: object;
}


call it like that 
Code:
const defaultPipeline: AggregatePipeLine = {
      $match: { _id: new ObjectId(id) },
      $project: {
        _id: 0,
        docs: {
          $slice: ["$users", urlQueryParam.OptionPagination.page
            , urlQueryParam.OptionPagination.limit]
        },
        totalDocs: { $size: "$users" }
      },
      $addFields: paginationFields(urlQueryParam.OptionPagination.limit, urlQueryParam.OptionPagination.page)
    };
await this.permissionModel.aggregate(pipeLine);

i developed functions aggretgaion for ci4

here s my code 


Quote:
PHP Code:
<?php

namespace Modules\Shared\Interfaces;


interface 
AggregationInterface
{
    public function aggregate(array $pipeLine): array;


    public function aggregatePagination(array $pipeLine): array;

 


PHP Code:
<?php

namespace Modules\Shared\Models;

use 
CodeIgniter\Model;
use 
Config\Services;
use 
Exception;
use 
Modules\Shared\Interfaces\AggregationInterface;

class 
Aggregation extends Model implements AggregationInterface
{


    public function aggregate(array $pipeLine): array
    {

        if (empty($pipeLine)) {
            throw  new Exception(' aggregate pile line can not be empty');
        }

        $builder $this->db->table($this->table);
        if (isset($pipeLine['select'])) {
            $builder->select($pipeLine['select']);
        }


        if (isset($pipeLine['join'])) {
            foreach ($pipeLine['join'] as $item) {
                $builder->join($item['table'], $item['condition'], $item['mode']);
            }

        }

        if (isset($pipeLine['whereIn'])) {
            $builder->whereIn($pipeLine['whereIn']['key'],$pipeLine['whereIn']['value']);
        }
        if (isset($pipeLine['whereNotIn'])) {
            $builder->whereNotIn($pipeLine['whereNotIn']['key'],$pipeLine['whereNotIn']['value']);
        }
        if (isset($pipeLine['orWhereIn'])) {
            $builder->orWhereIn($pipeLine['orWhereIn']['key'],$pipeLine['orWhereIn']['value']);
        }
        if (isset($pipeLine['orWhereNotIn'])) {
            $builder->orWhereNotIn($pipeLine['orWhereNotIn']['key'],$pipeLine['orWhereNotIn']['value']);
        }
        if (isset($pipeLine['where'])) {
            $builder->where($pipeLine['where']);
        }
        if (isset($pipeLine['orWhere'])) {
            $builder->orWhere($pipeLine['orWhere']);
        }
        if (isset($pipeLine['like'])) {
            $builder->like($pipeLine['like']);
        }
        if (isset($pipeLine['orLike'])) {
            $builder->orLike($pipeLine['orLike']);
        }
        if (isset($pipeLine['orNotLike'])) {
            $builder->orNotLike($pipeLine['orNotLike']);
        }
        if (isset($pipeLine['groupBy'])) {
            $builder->groupBy($pipeLine['groupBy']);
        }
        if (isset($pipeLine['having'])) {
            $builder->having($pipeLine['having']);
        }
        if (isset($pipeLine['orHaving'])) {
            $builder->orHaving($pipeLine['orHaving']);
        }

        if (isset($pipeLine['orHavingIn'])) {
            $builder->orHavingIn($pipeLine['orHavingIn']['key'],$pipeLine['orHavingIn']['value']);
        }
        if (isset($pipeLine['havingNotIn'])) {
            $builder->havingNotIn($pipeLine['orHavingIn']['key'],$pipeLine['orHavingIn']['value']);
        }
        if (isset($pipeLine['havingLike'])) {
            $builder->havingLike($pipeLine['havingLike']);
        }


        if (isset($pipeLine['sort']) && isset($pipeLine['order'])) {
            $builder->orderBy($pipeLine['sort'], $pipeLine['order']);
        }

        if (isset($pipeLine['limit'])) {
            $builder->limit($pipeLine['limit']);
        }
        if (isset($pipeLine['offset'])) {
            $builder->offset($pipeLine['offset']);
        }

        return $builder->get()->getCustomResultObject($this->returnType);

    }

    public function aggregatePagination(array $pipeLine): array
    {

        if (empty($pipeLine)) {
            throw  new Exception(' aggregate pile line can not be empty');
        }
        $builder $this->db->table($this->table);

        $builder->select($pipeLine['select']);

        if (isset($pipeLine['join'])) {
            foreach ($pipeLine['join'] as $item) {
                $builder->join($item['table'], $item['condition'], $item['mode']);
            }

        }


        if (isset($pipeLine['whereIn'])) {
            $builder->whereIn($pipeLine['whereIn']['key'],$pipeLine['whereIn']['value']);
        }
        if (isset($pipeLine['whereNotIn'])) {
            $builder->whereNotIn($pipeLine['whereNotIn']['key'],$pipeLine['whereNotIn']['value']);
        }
        if (isset($pipeLine['orWhereIn'])) {
            $builder->orWhereIn($pipeLine['orWhereIn']['key'],$pipeLine['orWhereIn']['value']);
        }
        if (isset($pipeLine['orWhereNotIn'])) {
            $builder->orWhereNotIn($pipeLine['orWhereNotIn']['key'],$pipeLine['orWhereNotIn']['value']);
        }
        if (isset($pipeLine['where'])) {
            $builder->where($pipeLine['where']);
        }
        if (isset($pipeLine['orWhere'])) {
            $builder->orWhere($pipeLine['orWhere']);
        }
        if (isset($pipeLine['like'])) {
            $builder->like($pipeLine['like']);
        }
        if (isset($pipeLine['orLike'])) {
            $builder->orLike($pipeLine['orLike']);
        }
        if (isset($pipeLine['orNotLike'])) {
            $builder->orNotLike($pipeLine['orNotLike']);
        }
        if (isset($pipeLine['groupBy'])) {
            $builder->groupBy($pipeLine['groupBy']);
        }
        if (isset($pipeLine['having'])) {
            $builder->having($pipeLine['having']);
        }
        if (isset($pipeLine['orHaving'])) {
            $builder->orHaving($pipeLine['orHaving']);
        }

        if (isset($pipeLine['orHavingIn'])) {
            $builder->orHavingIn($pipeLine['orHavingIn']['key'],$pipeLine['orHavingIn']['value']);
        }
        if (isset($pipeLine['havingNotIn'])) {
            $builder->havingNotIn($pipeLine['orHavingIn']['key'],$pipeLine['orHavingIn']['value']);
        }
        if (isset($pipeLine['havingLike'])) {
            $builder->havingLike($pipeLine['havingLike']);
        }

        if (isset($pipeLine['sort']) && isset($pipeLine['order'])) {
            $builder->orderBy($pipeLine['sort'], $pipeLine['order']);
        }
        if (isset($pipeLine['limit'])) {
            $builder->limit($pipeLine['limit']);
        }
        if (isset($pipeLine['page'])) {
            $offSet = ($pipeLine['page'] - 1) * $pipeLine['limit'];
            $builder->offset($offSet);
        }
        $pagination Services::pager(nullnullfalse);

        if (isset($pipeLine['offset']) && isset($pipeLine['limit']) && isset($pipeLine['page'])) {
            $pagination->setSegment($pipeLine['offset']);
            $paging $pipeLine['page'] >= $pipeLine['page'] : $pagination->getCurrentPage('default');
            $this->pager $pagination->store('default'$paging$pipeLine['limit'], $builder->countAllResults(false), $pipeLine['offset']);
        }

        return ['data' =>
            $builder->get()->getCustomResultObject($this->returnType),
            'pager' => $pagination->getDetails()

        ];

    }





the call aggregation  its need extend model from aggregation class then start to using it

PHP Code:
<?php namespace Modules\Common\Models;

use 
Modules\Common\Entities\SettingEntity;
use 
Modules\Shared\Models\Aggregation;

class  SettingModel extends Aggregation
{


    /**
    * table name
    */
    protected $primaryKey "id";
    protected $table "setting";

    /**
    * allowed Field
    */
    protected $allowedFields = [
        'key',
        'value',
        'description',
        'status',
        'deleted_at',
        'updated_at',
        'created_at'
    ];
    protected $useSoftDeletes false;
    protected $useTimestamps false;
    protected $createdField 'created_at';
    protected $updatedField 'updated_at';
    protected $returnType SettingEntity::class;
    protected $validationRules = [
        'key' => 'required|min_length[3]|max_length[255]|is_unique[setting.key]',
        'value' => 'required|min_length[3]|max_length[255]',
        'description' => 'required|min_length[3]|max_length[255]',
        'status' => 'required'
    ];
    protected $validationMessages = [];
    protected $skipValidation false;




that s way call  it in  aggregation 
PHP Code:
$pipeLine = [
            'select' => '*',
            'order' => 'desc',
            'sort' => 'id',
            'limit' => '10',
            'page' => '1',
            'offset' => '0'

        ];
        $data $this->model->aggregate($pipeLine);

        


PHP Code:
$pipeLine = [
            'select' => '*',
            'order' => 'desc',
            'sort' => 'id',
            'limit' => '10',
            'page' => '1',
            'offset' => '0'

        ];
        $data $this->model->aggregatePagination($pipeLine);

         

PHP Code:
$pipeLine = [
            'select' => 'news_sub_category.*,news_category.name as category,news_category.language',
            'join' => [
                ['table' => 'news_category',
                    'condition' => 'news_category.id = news_sub_category.category_id',
                    'mode' => 'left']
            ],
            'like' => ['news_sub_category.name' => 'i'],
            'order' => 'desc',
            'sort' => 'id',
            'limit' => '10',
            'page' => '1',
            'offset' => '0'

        ];
        $data $this->model->aggregatePagination($pipeLine); 

i hope ci4 developer add this feature for next version
its super usefull
This is a special case and does not affect the core of the framework in any way.
why not use builder, its has all those function
go there and see why wee needs aggregation functions
https://forum.codeigniter.com/thread-801...#pid390299