Cara menggunakan php aggregate

Pasti sebagian besar di antara kita Web Developer yang selama ini sudah menggunakan PHPMaker 2021, ingin menghapus kata TOTAL: (beserta karakter titik duanya), dan membuat cetakan tebal atau bold pada baris Aggregate di Aplikasi Web yang dihasilkannya. Tidak hanya itu, teks pada baris ini juga sering kali harus dibuat menjadi rata kanan, supaya lebih mudah terbaca.

Penyesuaian ini sering sekali dibutuhkan, mengingat Aplikasi Web yang dihasilkan oleh PHPMaker 2021 masih belum bisa memenuhi kebutuhan tadi. Teks seperti TOTAL: atau RATA-RATA: atau JUMLAH:, masih muncul sebelum angkanya, dan cetakan hurufnya pun belum bold atau tebal, serta belum rata kanan.

Yang dimaksud dengan baris Aggregate adalah baris yang menampilkan fungsi Penjumlahan (TOTAL), Rata-Rata (AVERAGE), atau Jumlah Item (COUNT) pada halaman List yang menampilkan data dalam bentuk table. Baris ini letaknya pada bagian paling bawah dari table tadi.

Oke deh, langsung saja ya. Supaya lebih mudah mengikutinya, kita mencoba menerapkannya pada project demo2021 yang bisa Anda download dari website resmi PHPMaker.

Pertama sekali, pastikan kita sudah membuka project tersebut dengan menggunakan PHPMaker 2021, lalu pada panel Database, klik table orderdetails. Selanjutnya, klik field Quantity, dan di sebelah kanan, pastikan tab Fields sudah terbuka.

Setelah itu, pilih TOTAL dari kolom List Page -> Aggregate, untuk memastikan field Quantity tadi menggunakan fungsi penjumlahan.

Berikutnya, klik tab Code (Server Events, Client Scripts and Custom Templates, lalu lompat ke lokasi ini: Server Events -> Table-Specific -> Common -> Row_Rendered, lalu masukkan kode ini ke dalam function Row_Rendered() tersebut:

    if ($this->RowType == ROWTYPE_AGGREGATE) {
        $this->Quantity->ViewValue = "<div style='text-align: right; font-weight: bold;'>" . $this->Quantity->ViewValue . "</div>";
    }

Kode di atas fungsinya untuk mengubah teks pada baris Aggregate pada field Quantity menjadi rata kanan dan cetakan tebal atau bold. Meskipun di kode tersebut kita sudah menghilangkan teks TOTAL:, namun bukan berarti hasilnya teks tersebut menjadi hilang.

Teks TOTAL: masih tetap kelihatan sebelum nilai penjumlahan tadi. Pertanyaan selanjutnya, bagaimana cara menghilangkan teks TOTAL?

Jawabannya, kita cukup menggunakan kode CSS. Caranya, klik icon HTML General Settings di toolbar PHPMaker 2021, lalu klik tab Styles -> User, kemudian masukkan kode berikut:

span.ew-aggregate {
    display: none;
}

Kode ini berfungsi untuk menghilangkan teks TOTAL: (ya, beserta karakter titik duanya sekalian).

Timbul pertanyaan lagi, mengapa tidak menggunakan kode jQuery saja untuk menyembunyikan bagian tersebut?

Jawabannya, kita tidak menggunakan jQuery, karena jika menggunakan jQuery, saat halaman List ditampilkan, maka tulisan TOTAL: sejenak masih muncul, lalu setelah itu akan ada jedah waktu sepersekian detik sampai tulisan TOTAL: menjadi hilang.

Tentu kurang bagus dan terkesan tidak profesional Aplikasi Web tersebut. Oleh karena itu, sangat disarankan untuk mengoptimalkan fitur CSS yang kode-nya bisa kita tambahkan sendiri dari bagian User Styles tadi.

Terakhir, pastikan jangan lupa untuk men-generate ulang semua file script menggunakan PHPMaker 2021, seperti biasa.

Lalu setelah itu, buka Aplikasi Web dari browser, dan pastikan sudah memuat ulang file .css yang terakhir di-generate oleh PHPMaker 2021 tadi. Lakukan hard refresh, atau tampilkan isi dari file .css tadi dari View Page Source.

Setelah login menggunakan username admin dan password master, lalu buka menu List Order Details, maka sekarang kita sudah tidak lagi melihat tulisan TOTAL: di baris aggregate dari table yang menampilkan data order details. Demikian juga nilai penjumlahannya sekarang ditampilkan dengan tulisan cetak tebal (bold), dan juga sudah rata kanan.

Betapa mudah dan cepatnya menerapkan kebutuhan tadi dari PHPMaker 2021. Hanya dengan sedikit kode PHP dan CSS itu saja, kita sudah bisa menyesuaikan teks pada baris Aggregate dari table yang terdapat di halaman List.

Singkatnya, proses agregasi dalam mongodb adalah memproses data (record) untuk dikumpulkan menjadi satu atau dipisah-pisah. 
Sebagai contoh terdapat data harga barang (nama, harga, kategori). Ingin mendapatkan harga rata-rata untuk tiap kategori barang, proses ini dinamakan agregasi.

Dalam tulisan kali ini saya akan langsung memberikan contoh kasus :

MongoDB menyinpan data dalam format JSON, dalam kasus kali ini data disimpan dengan format mempunyai format seperti dibawah ini. Data rating untuk masing-masing email (email == unique) dimana 1 email mempunyai child order, dan masing-masing order mempunyai child parameter dan nilai rating di setiap order.

/* 1 */
{
    "_id" : ObjectId("56d7c3d23004aa334327e109"),
    "_class" : "com.rating.SellerRate",
    "email" : "[email protected]",
    "orders" : [ 
        {
            "orderId" : "O1GT34QWKI",
            "rates" : [ 
                {
                    "param" : "QUALITY",
                    "rate" : 2.7999999523162842
                }, 
                {
                    "param" : "SERVICE",
                    "rate" : 1.0000000000000000
                }
            ]
        }, 
        {
            "orderId" : "OGHYJUKL",
            "rates" : [ 
                {
                    "param" : "QUALITY",
                    "rate" : 1.7000000476837158
                }, 
                {
                    "param" : "SERVICE",
                    "rate" : 3.2000000476837158
                }
            ]
        }
    ],
    "date" : "20160303",
    "createdBy" : "[email protected]",
    "modifiedBy" : "[email protected]",
    "creationTime" : NumberLong(1456980946865),
    "modificationTime" : NumberLong(1457326319159)
}

/* 2 */
{
    "_id" : ObjectId("56e6e6ecb5f1fbfb92892d20"),
     "_class" : "com.rating.SellerRate",
    "email" : "[email protected]",
    "orders" : [ 
        {
            "orderId" : "O1C45HWKI",
            "rates" : [ 
                {
                    "param" : "QUALITY",
                    "rate" : 2.7999999999999998
                }, 
                {
                    "param" : "SERVICE",
                    "rate" : 1.0000000000000000
                }
            ]
        }, 
        {
            "orderId" : "OF46JKJUKL",
            "rates" : [ 
                {
                    "param" : "QUALITY",
                    "rate" : 3.3999999999999999
                }, 
                {
                    "param" : "SERVICE",
                    "rate" : 4.2999999999999998
                }
            ]
        }
    ],
    "date" : "20160303",
    "createdBy" : "[email protected]",
    "modifiedBy" : "[email protected]",
    "creationTime" : NumberLong(1456980946865),
    "modificationTime" : NumberLong(1457326319159)
}

Expected Result :

[
   {
      "email":"[email protected]",
      "rates":[
         {
            "param":"SERVICE",
            "rate":2.100000023841858
         },
         {
            "param":"QUALITY",
            "rate":2.25
         }
      ]
   },
   {
      "email":"[email protected]",
      "rates":[
         {
            "param":"SERVICE",
            "rate":2.7
         },
         {
            "param":"QUALITY",
            "rate":1.5
         }
      ]
   }
]

Berikut, kurang lebih Query yang harus dijalankan agar mendapat hasil seperti yang di inginkan.

db.seller_rates.aggregate([
    {
        $unwind : "$orders"
    },
    {
        $unwind : "$orders.rates"
    },
    {
        $project : {
            email : "$email",
            param : "$orders.rates.param",
            rate : "$orders.rates.rate"
        }
    },
    {
        $group : {
            _id : {
                email : "$email", param : "$param"
            },
            rate : {
                $avg : "$rate"
            }
        }
    },
    {
        $project : {
            email : "$_id.email",
            param : "$_id.param",
            rate : "$rate"
        }
    },
    {
        $group : {
            _id : "$email",
            rates : { $push : "$$ROOT" }
        }
    }

])

$unwind

$unwind merupakan perintah untuk mengeluarkan child menjadi row. Dalam kasus ini 1 email mempunyai 2 orders, maka jika operasi { "$unwind" : "$orders"} gambaran singkatnya kurang lebih digambarkan dibawah ini, data awal :

{
   "email":"[email protected]",
   "orders":[
      {
         "orderId":"O1GT34QWKI",
         "rates":[
            {
               "param":"QUALITY",
               "rate":2.7999999523162842
            },
            {
               "param":"SERVICE",
               "rate":1.0000000000000000
            }
         ]
      },
      {
         "orderId":"OGHYJUKL",
         "rates":[
            {
               "param":"QUALITY",
               "rate":1.7000000476837158
            },
            {
               "param":"SERVICE",
               "rate":3.2000000476837158
            }
         ]
      }
   ]
}
Hasil $unwind :
{
   "result":[
      {
         "email":"[email protected]",
         "orders":{
            "orderId":"O1GTLAQWKI",
            "rates":[
               {
                  "param":"QUALITY",
                  "rate":2.7999999523162842
               },
               {
                  "param":"SERVICE",
                  "rate":1.0000000000000000
               }
            ]
         }
      },
      {
         "email":"[email protected]",
         "orders":{
            "orderId":"OGHYJUKL",
            "rates":[
               {
                  "param":"QUALITY",
                  "rate":1.7000000476837158
               },
               {
                  "param":"SERVICE",
                  "rate":3.2000000476837158
               }
            ]
         }
      }
   ]
}

$project

Operasi $project memungkinkan kita hanya memilih spesifik field yang akan ditampilkan. Contoh jika Query nya demikian (dengan menggunakan data existing).
db.seller_rates.aggregate([
    {
        $unwind : "$orders"
    },
    {
        $unwind : "$orders.rates"
    },
    {
        $project : {
            email : "$email",
            param : "$orders.rates.param",
            rate : "$orders.rates.rate"
        }
    }
])
Hasil $project :
/* 1 */
{
    "result" : [ 
        {
            "_id" : ObjectId("56d7c3d23004aa334327e109"),
            "email" : "[email protected]",
            "param" : "QUALITY",
            "rate" : 2.7999999523162842
        }, 
        {
            "_id" : ObjectId("56d7c3d23004aa334327e109"),
            "email" : "[email protected]",
            "param" : "SERVICE",
            "rate" : 1.0000000000000000
        }, 
        {
            "_id" : ObjectId("56d7c3d23004aa334327e109"),
            "email" : "[email protected]",
            "param" : "QUALITY",
            "rate" : 1.7000000476837158
        }, 
        {
            "_id" : ObjectId("56d7c3d23004aa334327e109"),
            "email" : "[email protected]",
            "param" : "SERVICE",
            "rate" : 3.2000000476837158
        }, 
        {
            "_id" : ObjectId("56e6e6ecb5f1fbfb92892d20"),
            "email" : "[email protected]",
            "param" : "QUALITY",
            "rate" : 2.7999999999999998
        }, 
        {
            "_id" : ObjectId("56e6e6ecb5f1fbfb92892d20"),
            "email" : "[email protected]",
            "param" : "SERVICE",
            "rate" : 1.0000000000000000
        }, 
        {
            "_id" : ObjectId("56e6e6ecb5f1fbfb92892d20"),
            "email" : "[email protected]",
            "param" : "QUALITY",
            "rate" : 3.3999999999999999
        }, 
        {
            "_id" : ObjectId("56e6e6ecb5f1fbfb92892d20"),
            "email" : "[email protected]",
            "param" : "SERVICE",
            "rate" : 4.2999999999999998
        }
    ],
    "ok" : 1.0000000000000000

}


$group

Jika dianalogikan dengan MySQL $group sama dengan operasi GROUP BY. Dalam kasus kita kali ini, bahwa ingin menghitung rata-rata rating berdasarkan email dan parameter. Berikut merupakan contoh query nya :
db.seller_rates.aggregate([
    {
        $unwind : "$orders"
    },
    {
        $unwind : "$orders.rates"
    },
    {
        $project : {
            email : "$email",
            param : "$orders.rates.param",
            rate : "$orders.rates.rate"
        }
    },
    {
        $group : {
            _id : {
                email : "$email", param : "$param"
            },
            rate : {
                $avg : "$rate"
            }
        }
    }

])
Hasil $group :
/* 1 */
{
    "result" : [ 
        {
            "_id" : {
                "email" : "[email protected]",
                "param" : "SERVICE"
            },
            "rate" : 2.6499999999999999
        }, 
        {
            "_id" : {
                "email" : "[email protected]",
                "param" : "SERVICE"
            },
            "rate" : 2.1000000238418579
        }, 
        {
            "_id" : {
                "email" : "[email protected]",
                "param" : "QUALITY"
            },
            "rate" : 3.0999999999999996
        }, 
        {
            "_id" : {
                "email" : "[email protected]",
                "param" : "QUALITY"
            },
            "rate" : 2.2500000000000000
        }
    ],
    "ok" : 1.0000000000000000
}
Pada hasil Query di atas, terlihat bahwa ada attribute “_id” selalu muncul, atibut ini yang digunakan sebagai key dalam operasi GROUP BY dan field “_id” merupakan mandatory ketika melakukan operasi GROUP BY. 

$push

$push merupakan operasi di dalam $group, satu level dengan $avg, $max, $sum, dll. Operasi $push akan mengembalikan array dari semua value dengan key yang sama.
Dari contoh query di bawah ini, dari hasil query sebelum nya, bahwa email dijadikan sebagai key, dan di push sebagai root dan attribut yang lain otomatis sebagai child (list of array).