{"id":93333,"date":"2025-11-28T23:42:27","date_gmt":"2025-11-28T16:42:27","guid":{"rendered":"https:\/\/itviec.com\/blog\/?p=93333"},"modified":"2025-12-10T14:16:27","modified_gmt":"2025-12-10T07:16:27","slug":"aggregate-trong-mongodb","status":"publish","type":"post","link":"https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/","title":{"rendered":"Aggregate trong MongoDB: C\u00e1ch c\u1ea3i thi\u1ec7n hi\u1ec7u su\u1ea5t truy v\u1ea5n"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_85 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">N\u1ed9i dung b\u00e0i vi\u1ebft<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/#Tong_quan_ve_MongoDB\" >T\u1ed5ng quan v\u1ec1 MongoDB<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/#Khai_niem_Aggregation_trong_DBMS_va_Aggregation_trong_MongoDB\" >Kh\u00e1i ni\u1ec7m Aggregation trong DBMS v\u00e0 Aggregation trong MongoDB<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/#Aggregate_pipeline_trong_MongoDB\" >Aggregate pipeline trong MongoDB<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/#Cach_thuc_thi_mot_Aggregate_bang_MongoDB\" >C\u00e1ch th\u1ef1c thi m\u1ed9t Aggregate b\u1eb1ng MongoDB<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/#Toi_uu_hoa_Aggregation_Pipeline_trong_MongoDB\" >T\u1ed1i \u01b0u h\u00f3a Aggregation Pipeline trong MongoDB<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/#Cac_cau_hoi_thuong_gap_ve_Aggregate_trong_MongoDB\" >C\u00e1c c\u00e2u h\u1ecfi th\u01b0\u1eddng g\u1eb7p v\u1ec1 Aggregate trong MongoDB<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/#Tong_ket\" >T\u1ed5ng k\u1ebft<\/a><\/li><\/ul><\/nav><\/div>\n\n<p><strong><em>Hi\u1ec7n nay, v\u1edbi s\u1ef1 gia t\u0103ng c\u1ee7a d\u1eef li\u1ec7u v\u00e0 y\u00eau c\u1ea7u v\u1ec1 t\u1ed1c \u0111\u1ed9 x\u1eed l\u00fd, c\u00e1c c\u00f4ng c\u1ee5 c\u01a1 s\u1edf d\u1eef li\u1ec7u nh\u01b0 MongoDB ng\u00e0y c\u00e0ng tr\u1edf n\u00ean quan tr\u1ecdng. Nh\u01b0ng ch\u1ec9 l\u01b0u tr\u1eef t\u1ed1t th\u00f4i ch\u01b0a \u0111\u1ee7, vi\u1ec7c t\u1ed1i \u01b0u h\u00f3a c\u00e1c truy v\u1ea5n m\u1edbi l\u00e0 y\u1ebfu t\u1ed1 then ch\u1ed1t \u0111\u1ec3 \u0111\u1ea3m b\u1ea3o hi\u1ec7u su\u1ea5t cao nh\u1ea5t khi l\u00e0m vi\u1ec7c v\u1edbi d\u1eef li\u1ec7u l\u1edbn. Aggregation trong MongoDB l\u00e0 c\u00f4ng c\u1ee5 quan tr\u1ecdng gi\u00fap b\u1ea1n c\u1ea3i thi\u1ec7n hi\u1ec7u n\u0103ng truy v\u1ea5n m\u1ed9t c\u00e1ch r\u00f5 r\u1ec7t.<\/em><\/strong><\/p>\n\n\n\n<p>\u0110\u1ecdc b\u00e0i vi\u1ebft n\u00e0y \u0111\u1ec3 hi\u1ec3u r\u00f5 h\u01a1n v\u1ec1:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Kh\u00e1i ni\u1ec7m aggregation trong DBSM l\u00e0 g\u00ec<\/li>\n\n\n\n<li>Aggregate pipeline<\/li>\n\n\n\n<li>C\u00e1ch th\u1ef1c thi m\u1ed9t Aggregate v\u1edbi MongoDB<\/li>\n\n\n\n<li>M\u1ed9t s\u1ed1 c\u00e1ch t\u1ed1i \u01b0u ho\u00e1 aggregate<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-t\u1ed5ng-quan-v\u1ec1-mongodb\"><span class=\"ez-toc-section\" id=\"Tong_quan_ve_MongoDB\"><\/span><strong>T\u1ed5ng quan v\u1ec1 MongoDB<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>MongoDB l\u00e0 m\u1ed9t h\u1ec7 qu\u1ea3n tr\u1ecb c\u01a1 s\u1edf d\u1eef li\u1ec7u NoSQL h\u01b0\u1edbng document, \u0111\u01b0\u1ee3c thi\u1ebft k\u1ebf \u0111\u1ec3 l\u01b0u tr\u1eef d\u1eef li\u1ec7u d\u01b0\u1edbi d\u1ea1ng BSON (Binary JSON) &#8211; m\u1ed9t phi\u00ean b\u1ea3n m\u1edf r\u1ed9ng c\u1ee7a JSON cho ph\u00e9p l\u01b0u tr\u1eef nhi\u1ec1u ki\u1ec3u d\u1eef li\u1ec7u h\u01a1n JSON thu\u1ea7n nh\u01b0 Date, ObjectId, Binary data, v\u00e0 h\u1ed7 tr\u1ee3 k\u00edch th\u01b0\u1edbc document l\u1edbn h\u01a1n. Thay v\u00ec l\u01b0u tr\u1eef trong c\u00e1c b\u1ea3ng, h\u00e0ng v\u00e0 c\u1ed9t nh\u01b0 c\u01a1 s\u1edf d\u1eef li\u1ec7u quan h\u1ec7 (SQL), MongoDB t\u1ed5 ch\u1ee9c d\u1eef li\u1ec7u theo m\u00f4 h\u00ecnh collection v\u00e0 document, gi\u00fap vi\u1ec7c m\u1edf r\u1ed9ng v\u00e0 thay \u0111\u1ed5i c\u1ea5u tr\u00fac d\u1eef li\u1ec7u d\u1ec5 d\u00e0ng h\u01a1n \u0111\u1ec3 th\u00edch \u1ee9ng v\u1edbi y\u00eau c\u1ea7u th\u1ef1c t\u1ebf.<\/p>\n\n\n\n<p>Nh\u1edd kh\u1ea3 n\u0103ng m\u1edf r\u1ed9ng theo chi\u1ec1u ngang (horizontal scaling) th\u00f4ng qua sharding v\u00e0 c\u01a1 ch\u1ebf replica set \u0111\u1ea3m b\u1ea3o t\u00ednh s\u1eb5n s\u00e0ng cao, MongoDB tr\u1edf th\u00e0nh l\u1ef1a ch\u1ecdn ph\u1ed5 bi\u1ebfn trong c\u00e1c \u1ee9ng d\u1ee5ng hi\u1ec7n \u0111\u1ea1i t\u1eeb n\u1ec1n t\u1ea3ng web, ph\u00e2n t\u00edch d\u1eef li\u1ec7u, \u0111\u1ebfn h\u1ec7 th\u1ed1ng IoT hay tr\u00ed tu\u1ec7 nh\u00e2n t\u1ea1o.&nbsp;<\/p>\n\n\n\n<p>Kh\u00f4ng ch\u1ec9 d\u1eebng l\u1ea1i \u1edf c\u00e1c thao t\u00e1c CRUD c\u01a1 b\u1ea3n (Create, Read, Update, Delete), MongoDB c\u00f2n n\u1ed5i b\u1eadt v\u1edbi <strong>Aggregation Framework<\/strong>, m\u1ed9t c\u00f4ng c\u1ee5 m\u1ea1nh m\u1ebd cho ph\u00e9p b\u1ea1n ph\u00e2n t\u00edch, t\u1ed5ng h\u1ee3p v\u00e0 bi\u1ebfn \u0111\u1ed5i d\u1eef li\u1ec7u ngay trong database, m\u00e0 kh\u00f4ng c\u1ea7n ph\u1ee5 thu\u1ed9c v\u00e0o c\u00f4ng c\u1ee5 x\u1eed l\u00fd b\u00ean ngo\u00e0i.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><em>\u0110\u1ecdc chi ti\u1ebft: <strong><a href=\"https:\/\/itviec.com\/blog\/mongodb-la-gi\/\" target=\"_blank\" rel=\"noreferrer noopener\">MongoDB l\u00e0 g\u00ec? \u0110\u1ecbnh ngh\u0129a v\u00e0 Hi\u1ec3u r\u00f5 A-Z v\u1ec1 MongoDB<\/a><\/strong><\/em><\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-khai-ni\u1ec7m-aggregation-trong-dbms-va-aggregation-trong-mongodb\"><span class=\"ez-toc-section\" id=\"Khai_niem_Aggregation_trong_DBMS_va_Aggregation_trong_MongoDB\"><\/span><strong>Kh\u00e1i ni\u1ec7m Aggregation trong DBMS v\u00e0 Aggregation trong MongoDB<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p><strong>Trong c\u00e1c h\u1ec7 qu\u1ea3n tr\u1ecb c\u01a1 s\u1edf d\u1eef li\u1ec7u (DBMS): <\/strong>Aggregation \u0111\u01b0\u1ee3c hi\u1ec3u l\u00e0 qu\u00e1 tr\u00ecnh t\u1ed5ng h\u1ee3p, ph\u00e2n t\u00edch v\u00e0 tr\u00edch xu\u1ea5t th\u00f4ng tin c\u00f3 \u00fd ngh\u0129a t\u1eeb m\u1ed9t t\u1eadp d\u1eef li\u1ec7u l\u1edbn. Ch\u1eb3ng h\u1ea1n, khi b\u1ea1n mu\u1ed1n th\u1ed1ng k\u00ea t\u1ed5ng doanh thu theo th\u00e1ng, t\u00ednh trung b\u00ecnh s\u1ed1 l\u01b0\u1ee3ng s\u1ea3n ph\u1ea9m b\u00e1n ra, hay nh\u00f3m d\u1eef li\u1ec7u theo danh m\u1ee5c, th\u00ec \u0111\u00f3 ch\u00ednh l\u00e0 c\u00e1c d\u1ea1ng c\u1ee7a ph\u00e9p t\u1ed5ng h\u1ee3p (aggregation).<\/p>\n\n\n\n<p>Trong MongoDB:\u00a0<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-aggregation-pipeline\"><strong>Aggregation Pipeline<\/strong><\/h3>\n\n\n\n<p>Aggregation Pipeline trong MongoDB l\u00e0 m\u1ed9t c\u01a1 ch\u1ebf x\u1eed l\u00fd d\u1eef li\u1ec7u theo chu\u1ed7i c\u00e1c giai \u0111o\u1ea1n (stages), m\u1ed7i stage th\u1ef1c hi\u1ec7n m\u1ed9t ph\u00e9p bi\u1ebfn \u0111\u1ed5i c\u1ee5 th\u1ec3 v\u00e0 k\u1ebft qu\u1ea3 c\u1ee7a stage tr\u01b0\u1edbc s\u1ebd \u0111\u01b0\u1ee3c truy\u1ec1n ti\u1ebfp cho stage sau.&nbsp;<\/p>\n\n\n\n<p>C\u00e1ch ti\u1ebfp c\u1eadn theo pipeline n\u00e0y gi\u00fap vi\u1ec7c x\u1eed l\u00fd tr\u1edf n\u00ean tr\u1ef1c quan, linh ho\u1ea1t v\u00e0 hi\u1ec7u qu\u1ea3, \u0111\u1eb7c bi\u1ec7t khi b\u1ea1n c\u1ea7n th\u1ef1c hi\u1ec7n nh\u1eefng ph\u00e9p t\u00ednh ho\u1eb7c th\u1ed1ng k\u00ea ph\u1ee9c t\u1ea1p ngay trong c\u01a1 s\u1edf d\u1eef li\u1ec7u m\u00e0 v\u1eabn \u0111\u1ea3m b\u1ea3o t\u1ed1c \u0111\u1ed9 v\u00e0 kh\u1ea3 n\u0103ng m\u1edf r\u1ed9ng.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-single-purpose-aggregation\"><strong>Single-purpose aggregation<\/strong><\/h3>\n\n\n\n<p>B\u00ean c\u1ea1nh Aggregation Pipeline v\u1edbi nhi\u1ec1u giai \u0111o\u1ea1n x\u1eed l\u00fd ph\u1ee9c t\u1ea1p, MongoDB c\u00f2n cung c\u1ea5p m\u1ed9t nh\u00f3m Single-purpose Aggregation operations &#8211; t\u1ee9c l\u00e0 nh\u1eefng ph\u00e9p t\u1ed5ng h\u1ee3p \u0111\u01a1n gi\u1ea3n, \u0111\u01b0\u1ee3c thi\u1ebft k\u1ebf cho c\u00e1c t\u00e1c v\u1ee5 th\u1ed1ng k\u00ea c\u01a1 b\u1ea3n v\u00e0 cho ph\u00e9p ng\u01b0\u1eddi d\u00f9ng nhanh ch\u00f3ng l\u1ea5y ra k\u1ebft qu\u1ea3 t\u1ed5ng h\u1ee3p m\u00e0 kh\u00f4ng c\u1ea7n x\u00e2y d\u1ef1ng pipeline nhi\u1ec1u b\u01b0\u1edbc.<\/p>\n\n\n\n<p>C\u00e1c h\u00e0m ph\u1ed5 bi\u1ebfn trong nh\u00f3m n\u00e0y g\u1ed3m c\u00f3:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>countDocuments()<\/code>: \u0111\u1ebfm s\u1ed1 l\u01b0\u1ee3ng document trong collection ho\u1eb7c theo \u0111i\u1ec1u ki\u1ec7n c\u1ee5 th\u1ec3.<\/li>\n\n\n\n<li><code>distinct()<\/code>: tr\u1ea3 v\u1ec1 danh s\u00e1ch c\u00e1c gi\u00e1 tr\u1ecb duy nh\u1ea5t c\u1ee7a m\u1ed9t tr\u01b0\u1eddng.<\/li>\n\n\n\n<li><code>estimatedDocumentCount()<\/code>: \u0111\u1ebfm nhanh s\u1ed1 l\u01b0\u1ee3ng document trong collection (s\u1eed d\u1ee5ng metadata, kh\u00f4ng scan to\u00e0n b\u1ed9 collection n\u00ean hi\u1ec7u n\u0103ng cao nh\u01b0ng k\u1ebft qu\u1ea3 l\u00e0 \u01b0\u1edbc l\u01b0\u1ee3ng, kh\u00f4ng h\u1ed7 tr\u1ee3 filter \u0111i\u1ec1u ki\u1ec7n).<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-cac-tr\u01b0\u1eddng-h\u1ee3p-s\u1eed-d\u1ee5ng\"><strong>C\u00e1c tr\u01b0\u1eddng h\u1ee3p s\u1eed d\u1ee5ng<\/strong><\/h3>\n\n\n\n<p>Single-purpose aggregation \u0111\u1eb7c bi\u1ec7t h\u1eefu \u00edch khi b\u1ea1n ch\u1ec9 c\u1ea7n th\u1ef1c hi\u1ec7n th\u1ed1ng k\u00ea nh\u1ecf, nhanh ch\u00f3ng nh\u01b0 ki\u1ec3m tra t\u1ed5ng s\u1ed1 b\u1ea3n ghi, \u0111\u1ebfm s\u1ed1 ng\u01b0\u1eddi d\u00f9ng hay li\u1ec7t k\u00ea c\u00e1c danh m\u1ee5c s\u1ea3n ph\u1ea9m kh\u00e1c nhau. So v\u1edbi pipeline, ch\u00fang \u0111\u01a1n gi\u1ea3n h\u01a1n, d\u1ec5 vi\u1ebft h\u01a1n v\u00e0 ch\u1ea1y nhanh h\u01a1n trong c\u00e1c tr\u01b0\u1eddng h\u1ee3p kh\u00f4ng y\u00eau c\u1ea7u x\u1eed l\u00fd ph\u1ee9c t\u1ea1p.&nbsp;<\/p>\n\n\n\n<p>Tuy nhi\u00ean, khi b\u00e0i to\u00e1n c\u1ea7n ph\u00e2n t\u00edch d\u1eef li\u1ec7u nhi\u1ec1u b\u01b0\u1edbc ho\u1eb7c t\u00ednh to\u00e1n n\u00e2ng cao, b\u1ea1n n\u00ean chuy\u1ec3n sang s\u1eed d\u1ee5ng Aggregation Pipeline \u0111\u1ec3 t\u1eadn d\u1ee5ng t\u1ed1i \u0111a s\u1ee9c m\u1ea1nh c\u1ee7a MongoDB.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-aggregate-pipeline-trong-mongodb\"><span class=\"ez-toc-section\" id=\"Aggregate_pipeline_trong_MongoDB\"><\/span><strong>Aggregate pipeline trong MongoDB<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-c\u1ea5u-truc-c\u01a1-b\u1ea3n-va-cach-ho\u1ea1t-d\u1ed9ng\"><strong>C\u1ea5u tr\u00fac c\u01a1 b\u1ea3n v\u00e0 c\u00e1ch ho\u1ea1t \u0111\u1ed9ng<\/strong><\/h3>\n\n\n\n<p>C\u00e1ch v\u1eadn h\u00e0nh Aggregate pipeline trong MongoDB t\u01b0\u01a1ng t\u1ef1 nh\u01b0 pipeline trong h\u1ec7 th\u1ed1ng x\u1eed l\u00fd d\u1eef li\u1ec7u gi\u00fap thao t\u00e1c, l\u1ecdc, t\u00ednh to\u00e1n v\u00e0 t\u1ed5ng h\u1ee3p d\u1eef li\u1ec7u m\u1ed9t c\u00e1ch c\u00f3 tr\u1eadt t\u1ef1 v\u00e0 hi\u1ec7u qu\u1ea3.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>M\u1ed7i stage trong pipeline s\u1ebd s\u1eed d\u1ee5ng m\u1ed9t to\u00e1n t\u1eed b\u1eaft \u0111\u1ea7u b\u1eb1ng d\u1ea5u <code>$<\/code>, th\u1ef1c hi\u1ec7n m\u1ed9t nhi\u1ec7m v\u1ee5 c\u1ee5 th\u1ec3 v\u00ed d\u1ee5 nh\u01b0 l\u1ecdc d\u1eef li\u1ec7u (<code>$match<\/code>), nh\u00f3m d\u1eef li\u1ec7u (<code>$group<\/code>), ch\u1ecdn tr\u01b0\u1eddng hi\u1ec3n th\u1ecb (<code>$project<\/code>) hay s\u1eafp x\u1ebfp k\u1ebft qu\u1ea3 (<code>$sort<\/code>).\u00a0<\/li>\n\n\n\n<li>D\u1eef li\u1ec7u output c\u1ee7a m\u1ed9t stage s\u1ebd tr\u1edf th\u00e0nh input c\u1ee7a stage ti\u1ebfp theo, t\u1ea1o th\u00e0nh m\u1ed9t lu\u1ed3ng x\u1eed l\u00fd li\u00ean t\u1ee5c (data flow).\u00a0<\/li>\n<\/ul>\n\n\n\n<p>C\u00fa ph\u00e1p c\u01a1 b\u1ea3n c\u1ee7a m\u1ed9t pipeline nh\u01b0 sau:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>db.collection.aggregate(&#91;\n  { &lt;stage1>: { &lt;expression> } },\n  { &lt;stage2>: { &lt;expression> } },\n  ...\n])<\/code><\/pre>\n\n\n\n<p>Vi\u1ec7c x\u00e2u chu\u1ed7i nhi\u1ec1u stage l\u1ea1i v\u1edbi nhau cho ph\u00e9p b\u1ea1n x\u00e2y d\u1ef1ng c\u00e1c lu\u1ed3ng x\u1eed l\u00fd d\u1eef li\u1ec7u ph\u1ee9c t\u1ea1p m\u00e0 v\u1eabn \u0111\u1ea3m b\u1ea3o hi\u1ec7u n\u0103ng cao, v\u00ec MongoDB th\u1ef1c thi pipeline tr\u1ef1c ti\u1ebfp tr\u00ean server thay v\u00ec ph\u1ea3i tr\u1ea3 d\u1eef li\u1ec7u v\u1ec1 client \u0111\u1ec3 x\u1eed l\u00fd.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-cac-stage-ph\u1ed5-bi\u1ebfn-trong-aggregate-nbsp\"><strong>C\u00e1c stage ph\u1ed5 bi\u1ebfn trong Aggregate&nbsp;<\/strong><\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>Stage<\/strong><\/td><td><strong>Ch\u1ee9c n\u0103ng ch\u00ednh<\/strong><\/td><td><strong>C\u00e1ch s\u1eed d\u1ee5ng<\/strong><\/td><\/tr><tr><td><code>$match<\/code><\/td><td>L\u1ecdc document theo \u0111i\u1ec1u ki\u1ec7n, t\u01b0\u01a1ng t\u1ef1 <code>WHERE<\/code> trong SQL. N\u00ean \u0111\u1eb7t s\u1edbm nh\u1ea5t c\u00f3 th\u1ec3 trong pipeline \u0111\u1ec3 gi\u1ea3m l\u01b0\u1ee3ng d\u1eef li\u1ec7u x\u1eed l\u00fd\u00a0<\/td><td>V\u00ed d\u1ee5 \u0111\u1ec3 l\u1ecdc ng\u01b0\u1eddi d\u00f9ng \u0111ang ho\u1ea1t \u0111\u1ed9ng v\u00e0 tr\u00ean 18 tu\u1ed5i:<br><code>{ $match: { status: \"active\", age: { $gte: 18 } } }<\/code><\/td><\/tr><tr><td><code>$group<\/code><\/td><td>Nh\u00f3m d\u1eef li\u1ec7u theo m\u1ed9t kh\u00f3a _id v\u00e0 \u00e1p d\u1ee5ng c\u00e1c ph\u00e9p t\u1ed5ng h\u1ee3p nh\u01b0 <code>$sum<\/code>, <code>$avg<\/code>, <code>$min<\/code>, <code>$max<\/code>.<\/td><td>V\u00ed d\u1ee5 \u0111\u1ec3 t\u00ednh t\u1ed5ng gi\u00e1 theo t\u1eebng lo\u1ea1i s\u1ea3n ph\u1ea9m:<br><code>{ $group: { _id: \"$category\", total: { $sum: \"$price\" } } }\u00a0<\/code><\/td><\/tr><tr><td><code>$project<\/code><\/td><td>Ch\u1ecdn tr\u01b0\u1eddng c\u1ea7n hi\u1ec3n th\u1ecb (1 \u0111\u1ec3 include, 0 \u0111\u1ec3 exclude) ho\u1eb7c t\u1ea1o tr\u01b0\u1eddng m\u1edbi d\u1ef1a tr\u00ean ph\u00e9p t\u00ednh.<\/td><td>V\u00ed d\u1ee5 \u0111\u1ec3 hi\u1ec3n th\u1ecb t\u00ean, t\u1ed5ng v\u00e0 t\u00ednh th\u00eam tr\u01b0\u1eddng gi\u1ea3m gi\u00e1:<br><code>{ $project: { name: 1, total: 1, discount: { $multiply: [\"$total\", 0.1] } } }\u00a0<\/code><\/td><\/tr><tr><td><code>$sort<\/code><\/td><td>S\u1eafp x\u1ebfp k\u1ebft qu\u1ea3 theo th\u1ee9 t\u1ef1 t\u0103ng\/gi\u1ea3m (1 cho t\u0103ng d\u1ea7n, -1 cho gi\u1ea3m d\u1ea7n).<\/td><td>V\u00ed d\u1ee5 \u0111\u1ec3 s\u1eafp x\u1ebfp gi\u1ea3m d\u1ea7n theo tr\u01b0\u1eddng total:<br><code>{ $sort: { total: -1 } }\u00a0<\/code><\/td><\/tr><tr><td><code>$limit<\/code><\/td><td>Gi\u1edbi h\u1ea1n s\u1ed1 l\u01b0\u1ee3ng document \u0111\u01b0\u1ee3c tr\u1ea3 v\u1ec1.<\/td><td>V\u00ed d\u1ee5 \u0111\u1ec3 l\u1ea5y 5 k\u1ebft qu\u1ea3 \u0111\u1ea7u ti\u00ean sau khi s\u1eafp x\u1ebfp.<br><code>{ $limit: 5 }\u00a0<\/code><\/td><\/tr><tr><td><code>$skip<\/code><\/td><td>B\u1ecf qua m\u1ed9t s\u1ed1 l\u01b0\u1ee3ng document \u0111\u1ea7u ti\u00ean, th\u01b0\u1eddng d\u00f9ng \u0111\u1ec3 ph\u00e2n trang. Tuy nhi\u00ean l\u01b0u \u00fd l\u00e0 s\u1ebd t\u1ed1n t\u00e0i nguy\u00ean v\u1edbi offset l\u1edbn.<\/td><td>V\u00ed d\u1ee5 \u0111\u1ec3 b\u1ecf qua 10 b\u1ea3n ghi \u0111\u1ea7u ti\u00ean:<br><code>{ $skip: 10 }\u00a0<\/code><\/td><\/tr><tr><td><code>$unwind<\/code><\/td><td>T\u00e1ch m\u1ea3ng (array) th\u00e0nh nhi\u1ec1u document ri\u00eang l\u1ebb, m\u1ed7i ph\u1ea7n t\u1eed trong m\u1ea3ng t\u01b0\u01a1ng \u1ee9ng v\u1edbi m\u1ed9t document.<br>C\u00f3 th\u1ec3 d\u00f9ng <code>preserveNullAndEmptyArrays: true<\/code> \u0111\u1ec3 gi\u1eef document kh\u00f4ng c\u00f3 array<\/td><td>\u0110\u1ec3 t\u00e1ch m\u1ed7i ph\u1ea7n t\u1eed trong m\u1ea3ng items th\u00e0nh d\u00f2ng ri\u00eang:<br><code>{ $unwind: \"$items\" }\u00a0<\/code><\/td><\/tr><tr><td><code>$lookup<\/code><\/td><td>Th\u1ef1c hi\u1ec7n \u201cjoin\u201d gi\u1eefa hai collection (gi\u1ed1ng <code>LEFT OUTER JOIN<\/code> trong SQL).<\/td><td>\u0110\u1ec3 g\u1ed9p d\u1eef li\u1ec7u ng\u01b0\u1eddi d\u00f9ng v\u00e0 \u0111\u01a1n h\u00e0ng:<br><code>{ $lookup: { from: \"orders\", localField: \"user_id\", foreignField: \"_id\", as: \"userOrders\" } }\u00a0<\/code><\/td><\/tr><tr><td><code>$count<\/code><\/td><td>\u0110\u1ebfm t\u1ed5ng s\u1ed1 document trong pipeline (sau c\u00e1c stage tr\u01b0\u1edbc \u0111\u00f3).<\/td><td>\u0110\u1ec3 tr\u1ea3 v\u1ec1 t\u1ed5ng s\u1ed1 b\u1ea3n ghi trong k\u1ebft qu\u1ea3:<br><code>{ $count: \"totalDocs\" }\u00a0<\/code><\/td><\/tr><tr><td><code>$addFields<\/code><\/td><td>Th\u00eam tr\u01b0\u1eddng m\u1edbi ho\u1eb7c c\u1eadp nh\u1eadt gi\u00e1 tr\u1ecb tr\u01b0\u1eddng hi\u1ec7n c\u00f3 m\u00e0 kh\u00f4ng lo\u1ea1i b\u1ecf c\u00e1c tr\u01b0\u1eddng kh\u00e1c.<\/td><td>\u0110\u1ec3 th\u00eam tr\u01b0\u1eddng revenue b\u1eb1ng hi\u1ec7u sales &#8211; cost:<br><code>{ $addFields: { revenue: { $subtract: [\"$sales\", \"$cost\"] } } }\u00a0<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-cach-th\u1ef1c-thi-m\u1ed9t-aggregate-b\u1eb1ng-mongodb\"><span class=\"ez-toc-section\" id=\"Cach_thuc_thi_mot_Aggregate_bang_MongoDB\"><\/span><strong>C\u00e1ch th\u1ef1c thi m\u1ed9t Aggregate b\u1eb1ng MongoDB<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>\u0110\u1ec3 th\u1ef1c thi m\u1ed9t Aggregate trong MongoDB, b\u1ea1n s\u1ebd s\u1eed d\u1ee5ng ph\u01b0\u01a1ng th\u1ee9c aggregate() tr\u00ean \u0111\u1ed1i t\u01b0\u1ee3ng collection.&nbsp;<\/p>\n\n\n\n<p>C\u00e1c b\u01b0\u1edbc th\u1ef1c hi\u1ec7n m\u1ed9t aggregate nh\u01b0 sau:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>X\u00e1c \u0111\u1ecbnh collection:<\/strong> \u0110\u1ea7u ti\u00ean, b\u1ea1n ph\u1ea3i x\u00e1c \u0111\u1ecbnh collection m\u00e0 b\u1ea1n mu\u1ed1n th\u1ef1c thi aggregate, v\u00ed d\u1ee5 <code>db.orders<\/code> ho\u1eb7c <code>db.products<\/code>.<\/li>\n\n\n\n<li><strong>X\u00e2y d\u1ef1ng pipeline:<\/strong> Ti\u1ebfp theo, x\u00e2y d\u1ef1ng pipeline b\u1eb1ng c\u00e1ch k\u1ebft h\u1ee3p c\u00e1c stage ph\u00f9 h\u1ee3p nh\u01b0 <code>$match<\/code>, <code>$group<\/code>, <code>$sort<\/code>, <code>$limit<\/code>,&#8230; t\u00f9y thu\u1ed9c v\u00e0o m\u1ee5c ti\u00eau ph\u00e2n t\u00edch c\u1ee7a b\u1ea1n.<\/li>\n\n\n\n<li><strong>G\u1ecdi ph\u01b0\u01a1ng th\u1ee9c <\/strong><code>aggregate()<\/code><strong>:<\/strong> Sau khi pipeline \u0111\u01b0\u1ee3c x\u00e2y d\u1ef1ng, b\u1ea1n g\u1ecdi ph\u01b0\u01a1ng th\u1ee9c <code>aggregate()<\/code> \u0111\u1ec3 th\u1ef1c thi c\u00e1c thao t\u00e1c. MongoDB s\u1ebd tr\u1ea3 v\u1ec1 m\u1ed9t cursor, kh\u00f4ng ph\u1ea3i m\u1ea3ng tr\u1ef1c ti\u1ebfp.<\/li>\n\n\n\n<li><strong>L\u1ecdc v\u00e0 hi\u1ec3n th\u1ecb k\u1ebft qu\u1ea3:<\/strong> B\u1ea1n c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng ph\u01b0\u01a1ng th\u1ee9c <code>toArray()<\/code> \u0111\u1ec3 l\u1ea5y k\u1ebft qu\u1ea3 d\u01b0\u1edbi d\u1ea1ng m\u1ea3ng ho\u1eb7c <code>forEach()<\/code>\u0111\u1ec3 duy\u1ec7t qua t\u1eebng document ho\u1eb7c s\u1eed d\u1ee5ng iterator pattern v\u1edbi <code>hasNext()<\/code> v\u00e0 <code>next()<\/code>.<\/li>\n<\/ol>\n\n\n\n<p>V\u00ed d\u1ee5: Gi\u1ea3 s\u1eed b\u1ea1n c\u00f3 m\u1ed9t collection orders v\u00e0 mu\u1ed1n t\u1ed5ng h\u1ee3p t\u1ed5ng s\u1ed1 \u0111\u01a1n h\u00e0ng theo t\u1eebng <code>customer_id<\/code> ta th\u1ef1c hi\u1ec7n nh\u01b0 sau:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>db.orders.aggregate(&#91;\n  { $match: { status: \"completed\" } },  \/\/ Ch\u1ec9 l\u1ea5y c\u00e1c \u0111\u01a1n h\u00e0ng \u0111\u00e3 ho\u00e0n th\u00e0nh\n  { $group: { _id: \"$customer_id\", totalAmount: { $sum: \"$amount\" } } },  \/\/ Nh\u00f3m theo customer_id v\u00e0 t\u00ednh t\u1ed5ng ti\u1ec1n\n  { $sort: { totalAmount: -1 } },        \/\/ S\u1eafp x\u1ebfp theo t\u1ed5ng ti\u1ec1n gi\u1ea3m d\u1ea7n\n  { $limit: 10 }                         \/\/ L\u1ea5y 10 kh\u00e1ch h\u00e0ng c\u00f3 t\u1ed5ng ti\u1ec1n cao nh\u1ea5t\n]).forEach(printjson);<\/code><\/pre>\n\n\n\n<p>K\u1ebft qu\u1ea3 s\u1ebd l\u00e0 m\u1ed9t danh s\u00e1ch c\u00e1c kh\u00e1ch h\u00e0ng v\u1edbi t\u1ed5ng s\u1ed1 ti\u1ec1n \u0111\u00e3 chi ti\u00eau trong c\u00e1c \u0111\u01a1n h\u00e0ng ho\u00e0n th\u00e0nh, \u0111\u01b0\u1ee3c s\u1eafp x\u1ebfp t\u1eeb cao xu\u1ed1ng th\u1ea5p, gi\u1edbi h\u1ea1n trong 10 kh\u00e1ch h\u00e0ng \u0111\u1ea7u ti\u00ean.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-t\u1ed1i-\u01b0u-hoa-aggregation-pipeline-trong-mongodb\"><span class=\"ez-toc-section\" id=\"Toi_uu_hoa_Aggregation_Pipeline_trong_MongoDB\"><\/span><strong>T\u1ed1i \u01b0u h\u00f3a Aggregation Pipeline trong MongoDB<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-s\u1eed-d\u1ee5ng-match-s\u1edbm-trong-pipeline\"><strong>S\u1eed d\u1ee5ng <\/strong>$match<strong> s\u1edbm trong pipeline<\/strong><\/h3>\n\n\n\n<p>Khi th\u1ef1c hi\u1ec7n m\u1ed9t pipeline, giai \u0111o\u1ea1n <code>$match<\/code> th\u01b0\u1eddng \u0111\u01b0\u1ee3c s\u1eed d\u1ee5ng \u0111\u1ec3 l\u1ecdc d\u1eef li\u1ec7u d\u1ef1a tr\u00ean \u0111i\u1ec1u ki\u1ec7n nh\u1ea5t \u0111\u1ecbnh. \u0110\u1eb7t <code>$match<\/code> \u1edf giai \u0111o\u1ea1n \u0111\u1ea7u ti\u00ean c\u1ee7a pipeline s\u1ebd gi\u00fap gi\u1ea3m s\u1ed1 l\u01b0\u1ee3ng document c\u1ea7n ph\u1ea3i x\u1eed l\u00fd trong c\u00e1c giai \u0111o\u1ea1n sau.<\/p>\n\n\n\n<p>Vi\u1ec7c l\u1ecdc d\u1eef li\u1ec7u s\u1edbm gi\u00fap ti\u1ebft ki\u1ec7m t\u00e0i nguy\u00ean v\u00e0 l\u00e0m gi\u1ea3m \u0111\u1ed9 ph\u1ee9c t\u1ea1p c\u1ee7a c\u00e1c thao t\u00e1c sau n\u00e0y. Quan tr\u1ecdng h\u01a1n, MongoDB c\u00f3 th\u1ec3 t\u1eadn d\u1ee5ng indexes cho <code>$match<\/code> khi n\u00f3 \u0111\u01b0\u1ee3c \u0111\u1eb7t \u1edf \u0111\u1ea7u pipeline.<\/p>\n\n\n\n<p>V\u00ed d\u1ee5 \u0111\u1ec3 l\u1ecdc c\u00e1c \u0111\u01a1n h\u00e0ng \u0111\u00e3 ho\u00e0n th\u00e0nh v\u00e0 t\u00ednh t\u1ed5ng s\u1ed1 ti\u1ec1n m\u00e0 m\u1ed7i kh\u00e1ch h\u00e0ng \u0111\u00e3 chi ti\u00eau ta c\u00f3 c\u00fa ph\u00e1p nh\u01b0 sau:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>db.orders.aggregate(&#91;\n  { $match: { status: \"completed\" } },  \/\/ L\u1ecdc d\u1eef li\u1ec7u ngay t\u1eeb \u0111\u1ea7u\n  { $group: { _id: \"$customer_id\", totalAmount: { $sum: \"$amount\" } } },\n  { $sort: { totalAmount: -1 } },\n  { $limit: 10 }\n])<\/code><\/pre>\n\n\n\n<p>Trong \u0111\u00f3:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>$match<\/code> \u1edf \u0111\u1ea7u pipeline gi\u00fap l\u1ecdc c\u00e1c \u0111\u01a1n h\u00e0ng c\u00f3 tr\u1ea1ng th\u00e1i &#8220;completed&#8221;. Vi\u1ec7c n\u00e0y gi\u00fap gi\u1ea3m s\u1ed1 l\u01b0\u1ee3ng d\u1eef li\u1ec7u c\u1ea7n ph\u1ea3i x\u1eed l\u00fd trong c\u00e1c b\u01b0\u1edbc ti\u1ebfp theo nh\u01b0 <code>$group<\/code> v\u00e0 <code>$sort<\/code>, t\u1eeb \u0111\u00f3 t\u0103ng t\u1ed1c \u0111\u1ed9 truy v\u1ea5n.\u00a0<\/li>\n\n\n\n<li>N\u1ebfu <code>$match<\/code> \u0111\u01b0\u1ee3c \u0111\u1eb7t sau giai \u0111o\u1ea1n <code>$group<\/code> ho\u1eb7c <code>$sort<\/code>, MongoDB s\u1ebd ph\u1ea3i x\u1eed l\u00fd to\u00e0n b\u1ed9 collection tr\u01b0\u1edbc khi l\u1ecdc, l\u00e0m gi\u1ea3m hi\u1ec7u su\u1ea5t \u0111\u00e1ng k\u1ec3.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-dung-project-sau-khi-nhom-d\u1eef-li\u1ec7u\"><strong>D\u00f9ng <\/strong>$project<strong> sau khi nh\u00f3m d\u1eef li\u1ec7u<\/strong><\/h3>\n\n\n\n<p>Khi s\u1eed d\u1ee5ng <code>$group<\/code>, c\u00f3 th\u1ec3 t\u1ea1o th\u00eam tr\u01b0\u1eddng b\u1eb1ng <code>$project<\/code> \u0111\u1ec3 l\u1ecdc v\u00e0 t\u00ednh to\u00e1n c\u00e1c tr\u01b0\u1eddng c\u1ea7n thi\u1ebft sau khi \u0111\u00e3 nh\u00f3m d\u1eef li\u1ec7u. Vi\u1ec7c s\u1eed d\u1ee5ng <code>$project<\/code> sau giai \u0111o\u1ea1n <code>$group<\/code> gi\u00fap l\u1ecdc c\u00e1c tr\u01b0\u1eddng kh\u00f4ng c\u1ea7n thi\u1ebft v\u00e0 t\u00ednh to\u00e1n c\u00e1c tr\u01b0\u1eddng m\u1edbi m\u00e0 kh\u00f4ng l\u00e0m ph\u1ee9c t\u1ea1p d\u1eef li\u1ec7u qu\u00e1 nhi\u1ec1u.<\/p>\n\n\n\n<p>Tuy nhi\u00ean, c\u1ea7n l\u01b0u \u00fd r\u1eb1ng vi\u1ec7c project s\u1edbm tr\u01b0\u1edbc <code>$group<\/code> c\u0169ng c\u00f3 th\u1ec3 t\u1ed1i \u01b0u b\u1eb1ng c\u00e1ch gi\u1ea3m d\u1eef li\u1ec7u c\u1ea7n x\u1eed l\u00fd.<\/p>\n\n\n\n<p>V\u00ed d\u1ee5 \u0111\u1ec3 lo\u1ea1i b\u1ecf c\u00e1c tr\u01b0\u1eddng kh\u00f4ng c\u1ea7n thi\u1ebft v\u00e0 ch\u1ec9 gi\u1eef l\u1ea1i nh\u1eefng th\u00f4ng tin quan tr\u1ecdng nh\u01b0 sau:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>db.orders.aggregate(&#91;\n  { $match: { status: \"completed\" } },\n  { $group: { _id: \"$customer_id\", totalAmount: { $sum: \"$amount\" } } },\n  { $project: { totalAmount: 1, _id: 0 } },  \/\/ Ch\u1ec9 gi\u1eef l\u1ea1i tr\u01b0\u1eddng totalAmount\n  { $sort: { totalAmount: -1 } },\n  { $limit: 10 }\n])<\/code><\/pre>\n\n\n\n<p>\u1ede v\u00ed d\u1ee5 n\u00e0y, sau khi nh\u00f3m c\u00e1c \u0111\u01a1n h\u00e0ng theo <code>customer_id<\/code> v\u00e0 t\u00ednh t\u1ed5ng s\u1ed1 ti\u1ec1n (<code>totalAmount<\/code>), ch\u00fang ta s\u1eed d\u1ee5ng <code>$project<\/code> \u0111\u1ec3 \u0111\u1ed5i t\u00ean tr\u01b0\u1eddng <code>_id<\/code> th\u00e0nh customer cho d\u1ec5 hi\u1ec3u v\u00e0 ch\u1ec9 gi\u1eef l\u1ea1i tr\u01b0\u1eddng totalAmount v\u00e0 lo\u1ea1i b\u1ecf tr\u01b0\u1eddng <code>_id<\/code>.<\/p>\n\n\n\n<p>\u0110i\u1ec1u n\u00e0y gi\u00fap gi\u1ea3m k\u00edch th\u01b0\u1edbc d\u1eef li\u1ec7u m\u00e0 MongoDB ph\u1ea3i x\u1eed l\u00fd v\u00e0 truy\u1ec1n qua c\u00e1c giai \u0111o\u1ea1n ti\u1ebfp theo. Khi b\u1ea1n ch\u1ec9 gi\u1eef l\u1ea1i nh\u1eefng tr\u01b0\u1eddng c\u1ea7n thi\u1ebft, b\u1ea1n s\u1ebd ti\u1ebft ki\u1ec7m t\u00e0i nguy\u00ean b\u1ed9 nh\u1edb v\u00e0 gi\u00fap pipeline ch\u1ea1y nhanh h\u01a1n.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-t\u1ed1i-\u01b0u-hoa-sort-va-limit\"><strong>T\u1ed1i \u01b0u h\u00f3a <\/strong>$sort<strong> v\u00e0 <\/strong>$limit<\/h3>\n\n\n\n<p>MongoDB t\u1ef1 \u0111\u1ed9ng t\u1ed1i \u01b0u khi <code>$sort<\/code> v\u00e0 <code>$limit<\/code> li\u1ec1n k\u1ec1 nhau. Khi hai stage n\u00e0y \u0111\u1ee9ng c\u1ea1nh nhau, MongoDB s\u1ebd ch\u1ec9 gi\u1eef trong b\u1ed9 nh\u1edb s\u1ed1 l\u01b0\u1ee3ng document b\u1eb1ng v\u1edbi gi\u1edbi h\u1ea1n c\u1ee7a <code>$limit<\/code>, gi\u00fap ti\u1ebft ki\u1ec7m t\u00e0i nguy\u00ean \u0111\u00e1ng k\u1ec3.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>db.orders.aggregate(&#91;\n  { $match: { status: \"completed\" } },\n  { $sort: { amount: -1 } },  \/\/ Sort tr\u01b0\u1edbc\n  { $limit: 1000 },           \/\/ Limit sau - MongoDB t\u1ef1 \u0111\u1ed9ng t\u1ed1i \u01b0u\n  { $group: { _id: \"$customer_id\", totalAmount: { $sum: \"$amount\" } } }\n])<\/code><\/pre>\n\n\n\n<p>\u1ede v\u00ed d\u1ee5 n\u00e0y, tr\u01b0\u1edbc khi th\u1ef1c hi\u1ec7n <code>$sort<\/code>, ch\u00fang ta gi\u1edbi h\u1ea1n s\u1ed1 l\u01b0\u1ee3ng document v\u1edbi <code>$limit<\/code> \u0111\u1ec3 ch\u1ec9 s\u1eafp x\u1ebfp m\u1ed9t ph\u1ea7n d\u1eef li\u1ec7u thay v\u00ec to\u00e0n b\u1ed9 collection. N\u1ebfu kh\u00f4ng gi\u1edbi h\u1ea1n d\u1eef li\u1ec7u, MongoDB s\u1ebd ph\u1ea3i s\u1eafp x\u1ebfp t\u1ea5t c\u1ea3 c\u00e1c document, l\u00e0m gi\u1ea3m hi\u1ec7u su\u1ea5t v\u00e0 t\u1ed1n nhi\u1ec1u t\u00e0i nguy\u00ean.<\/p>\n\n\n\n<p>B\u1eb1ng c\u00e1ch gi\u1edbi h\u1ea1n d\u1eef li\u1ec7u tr\u01b0\u1edbc khi s\u1eafp x\u1ebfp, ch\u00fang ta gi\u1ea3m \u0111\u01b0\u1ee3c s\u1ed1 l\u01b0\u1ee3ng document c\u1ea7n x\u1eed l\u00fd trong giai \u0111o\u1ea1n <code>$sort<\/code>, gi\u00fap pipeline th\u1ef1c thi nhanh h\u01a1n.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-t\u1eadn-d\u1ee5ng-indexes\"><strong>T\u1eadn d\u1ee5ng Indexes<\/strong><\/h3>\n\n\n\n<p>MongoDB c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng indexes \u0111\u1ec3 t\u0103ng t\u1ed1c c\u00e1c truy v\u1ea5n. \u0110\u1ea3m b\u1ea3o r\u1eb1ng c\u00e1c tr\u01b0\u1eddng m\u00e0 b\u1ea1n s\u1eed d\u1ee5ng trong <code>$match<\/code>, <code>$sort<\/code> hay <code>$group<\/code> \u0111\u1ec1u \u0111\u01b0\u1ee3c index h\u00f3a \u0111\u00fang c\u00e1ch. \u0110\u1eb7c bi\u1ec7t, c\u00e1c tr\u01b0\u1eddng \u0111\u01b0\u1ee3c s\u1eed d\u1ee5ng trong <code>$match<\/code> v\u00e0 <code>$sort<\/code> s\u1ebd gi\u00fap MongoDB t\u00ecm ki\u1ebfm v\u00e0 truy xu\u1ea5t d\u1eef li\u1ec7u nhanh ch\u00f3ng, gi\u1ea3m th\u1eddi gian x\u1eed l\u00fd.<\/p>\n\n\n\n<p>L\u01b0u \u00fd quan tr\u1ecdng v\u1ec1 indexes:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>$match<\/code> c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng index khi \u1edf \u0111\u1ea7u pipeline<\/li>\n\n\n\n<li><code>$sort<\/code> c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng index n\u1ebfu n\u00f3 \u0111\u1ee9ng ngay sau <code>$match<\/code> \u0111\u1ea7u ti\u00ean Compound index ph\u1ea3i kh\u1edbp v\u1edbi th\u1ee9 t\u1ef1 c\u00e1c tr\u01b0\u1eddng trong query<\/li>\n<\/ul>\n\n\n\n<p>V\u00ed d\u1ee5 v\u1ec1 \u1ee9ng d\u1ee5ng s\u1eed d\u1ee5ng index cho truy v\u1ea5n nhanh h\u01a1n nh\u01b0 sau:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>db.orders.createIndex({ status: 1, amount: -1 })  \/\/ T\u1ea1o index cho c\u00e1c tr\u01b0\u1eddng status v\u00e0 amount\n\ndb.orders.aggregate(&#91;\n  { $match: { status: \"completed\" } },\n  { $sort: { amount: -1 } },\n  { $group: { _id: \"$customer_id\", totalAmount: { $sum: \"$amount\" } } }\n])<\/code><\/pre>\n\n\n\n<p>Trong v\u00ed d\u1ee5 n\u00e0y, ch\u00fang ta t\u1ea1o m\u1ed9t compound index cho c\u00e1c tr\u01b0\u1eddng status v\u00e0 amount. MongoDB c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng index n\u00e0y \u0111\u1ec3 t\u00ecm ki\u1ebfm v\u00e0 s\u1eafp x\u1ebfp d\u1eef li\u1ec7u nhanh ch\u00f3ng, thay v\u00ec ph\u1ea3i qu\u00e9t to\u00e0n b\u1ed9 collection, gi\u00fap gi\u1ea3m \u0111\u00e1ng k\u1ec3 th\u1eddi gian truy v\u1ea5n v\u00e0 t\u0103ng hi\u1ec7u su\u1ea5t, \u0111\u1eb7c bi\u1ec7t khi l\u00e0m vi\u1ec7c v\u1edbi d\u1eef li\u1ec7u l\u1edbn.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-s\u1eed-d\u1ee5ng-facet-cho-phep-phan-tich-d\u1ed3ng-th\u1eddi\"><strong>S\u1eed d\u1ee5ng <\/strong>$facet<strong> cho ph\u00e9p ph\u00e2n t\u00edch \u0111\u1ed3ng th\u1eddi<\/strong><\/h3>\n\n\n\n<p><code>$facet<\/code> cho ph\u00e9p b\u1ea1n th\u1ef1c hi\u1ec7n nhi\u1ec1u pipeline song song trong m\u1ed9t truy v\u1ea5n duy nh\u1ea5t, gi\u00fap ph\u00e2n t\u00edch nhi\u1ec1u kh\u00eda c\u1ea1nh c\u1ee7a d\u1eef li\u1ec7u c\u00f9ng l\u00fac m\u00e0 kh\u00f4ng c\u1ea7n ph\u1ea3i vi\u1ebft nhi\u1ec1u truy v\u1ea5n ri\u00eang bi\u1ec7t.<\/p>\n\n\n\n<p>Tuy nhi\u00ean, c\u1ea7n l\u01b0u \u00fd <code>$facet<\/code> c\u00f3 gi\u1edbi h\u1ea1n 16MB cho output v\u00e0 kh\u00f4ng th\u1ec3 s\u1eed d\u1ee5ng indexes cho c\u00e1c stage b\u00ean trong.<\/p>\n\n\n\n<p>V\u00ed d\u1ee5 \u0111\u1ec3 ph\u00e2n t\u00edch \u0111\u1ed3ng th\u1eddi v\u1edbi <code>$facet:<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>db.orders.aggregate(&#91;\n  { $match: { status: \"completed\" } },\n  { $facet: {\n      totalRevenue: &#91;{ $group: { _id: null, total: { $sum: \"$amount\" } } }],\n      averageOrder: &#91;{ $group: { _id: null, avg: { $avg: \"$amount\" } } }]\n    }\n  }\n])<\/code><\/pre>\n\n\n\n<p>\u1ede v\u00ed d\u1ee5 n\u00e0y, ch\u00fang ta s\u1eed d\u1ee5ng <code>$facet<\/code> \u0111\u1ec3 th\u1ef1c hi\u1ec7n hai ph\u00e9p ph\u00e2n t\u00edch \u0111\u1ed3ng th\u1eddi: t\u00ednh t\u1ed5ng doanh thu (<code>totalRevenue<\/code>) v\u00e0 t\u00ednh gi\u00e1 tr\u1ecb trung b\u00ecnh c\u1ee7a \u0111\u01a1n h\u00e0ng (<code>averageOrder<\/code>). Vi\u1ec7c n\u00e0y gi\u00fap t\u0103ng hi\u1ec7u su\u1ea5t v\u00ec b\u1ea1n ch\u1ec9 c\u1ea7n th\u1ef1c hi\u1ec7n m\u1ed9t truy v\u1ea5n duy nh\u1ea5t thay v\u00ec hai truy v\u1ea5n ri\u00eang bi\u1ec7t.<\/p>\n\n\n\n<p>Tuy nhi\u00ean, v\u1edbi d\u1eef li\u1ec7u r\u1ea5t l\u1edbn, vi\u1ec7c ch\u1ea1y c\u00e1c query ri\u00eang c\u00f3 th\u1ec3 hi\u1ec7u qu\u1ea3 h\u01a1n do c\u00f3 th\u1ec3 t\u1eadn d\u1ee5ng indexes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-cac-cau-h\u1ecfi-th\u01b0\u1eddng-g\u1eb7p-v\u1ec1-aggregate-trong-mongodb\"><span class=\"ez-toc-section\" id=\"Cac_cau_hoi_thuong_gap_ve_Aggregate_trong_MongoDB\"><\/span><strong>C\u00e1c c\u00e2u h\u1ecfi th\u01b0\u1eddng g\u1eb7p v\u1ec1 Aggregate trong MongoDB<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-aggregation-co-nhanh-h\u01a1n-truy-v\u1ea5n-thong-th\u01b0\u1eddng-khong\"><strong>Aggregation c\u00f3 nhanh h\u01a1n truy v\u1ea5n th\u00f4ng th\u01b0\u1eddng kh\u00f4ng?<\/strong><\/h3>\n\n\n\n<p>Aggregation c\u00f3 th\u1ec3 nhanh h\u01a1n ho\u1eb7c ch\u1eadm h\u01a1n so v\u1edbi c\u00e1c truy v\u1ea5n th\u00f4ng th\u01b0\u1eddng t\u00f9y thu\u1ed9c v\u00e0o c\u00e1c y\u1ebfu t\u1ed1 nh\u01b0 lo\u1ea1i truy v\u1ea5n, k\u00edch th\u01b0\u1edbc d\u1eef li\u1ec7u v\u00e0 c\u1ea5u tr\u00fac index.<\/p>\n\n\n\n<p><strong>Khi n\u00e0o Aggregation nhanh h\u01a1n?<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Aggregation r\u1ea5t m\u1ea1nh trong c\u00e1c t\u00e1c v\u1ee5 t\u00ednh to\u00e1n, nh\u00f3m d\u1eef li\u1ec7u v\u00e0 ph\u00e2n t\u00edch ph\u1ee9c t\u1ea1p m\u00e0 kh\u00f4ng c\u1ea7n ph\u1ea3i xu\u1ea5t d\u1eef li\u1ec7u ra ngo\u00e0i. N\u00f3 c\u00f3 th\u1ec3 th\u1ef1c hi\u1ec7n c\u00e1c ph\u00e9p to\u00e1n ph\u1ee9c t\u1ea1p ngay trong c\u01a1 s\u1edf d\u1eef li\u1ec7u m\u00e0 kh\u00f4ng ph\u1ea3i chuy\u1ec3n d\u1eef li\u1ec7u qua \u1ee9ng d\u1ee5ng, \u0111i\u1ec1u n\u00e0y gi\u00fap gi\u1ea3m \u0111\u1ed9 tr\u1ec5 network I\/O v\u00e0 t\u00e0i nguy\u00ean CPU ph\u00eda client khi b\u1ea1n th\u1ef1c hi\u1ec7n c\u00e1c ph\u00e9p t\u00ednh ph\u1ee9c t\u1ea1p nh\u01b0 t\u00ednh t\u1ed5ng, nh\u00f3m, ho\u1eb7c s\u1eafp x\u1ebfp.<\/li>\n\n\n\n<li>Aggregation t\u1eadn d\u1ee5ng \u0111\u01b0\u1ee3c c\u00e1c t\u1ed1i \u01b0u h\u00f3a n\u1ed9i b\u1ed9 c\u1ee7a MongoDB nh\u01b0 pipeline optimization, index usage, v\u00e0 c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng disk khi c\u1ea7n v\u1edbi option <code>allowDiskUse: true<\/code><\/li>\n<\/ul>\n\n\n\n<p><strong>Khi n\u00e0o Aggregation ch\u1eadm h\u01a1n?<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Aggregation c\u00f3 th\u1ec3 ch\u1eadm h\u01a1n so v\u1edbi truy v\u1ea5n th\u00f4ng th\u01b0\u1eddng n\u1ebfu kh\u00f4ng \u0111\u01b0\u1ee3c t\u1ed1i \u01b0u h\u00f3a \u0111\u00fang c\u00e1ch, \u0111\u1eb7c bi\u1ec7t l\u00e0 n\u1ebfu kh\u00f4ng s\u1eed d\u1ee5ng index ph\u00f9 h\u1ee3p trong c\u00e1c giai \u0111o\u1ea1n nh\u01b0 <code>$match<\/code>, <code>$sort<\/code> ho\u1eb7c <code>$group<\/code>.\u00a0<\/li>\n\n\n\n<li>V\u1edbi c\u00e1c truy v\u1ea5n \u0111\u01a1n gi\u1ea3n ch\u1ec9 c\u1ea7n l\u1ecdc v\u00e0 l\u1ea5y d\u1eef li\u1ec7u th\u00ec <code>find()<\/code> th\u01b0\u1eddng nhanh h\u01a1n v\u00ec c\u00f3 overhead \u00edt h\u01a1n.<\/li>\n\n\n\n<li>C\u00e1c pipeline ph\u1ee9c t\u1ea1p v\u1edbi nhi\u1ec1u giai \u0111o\u1ea1n ho\u1eb7c khi x\u1eed l\u00fd d\u1eef li\u1ec7u kh\u00f4ng \u0111\u01b0\u1ee3c ph\u00e2n t\u00e1n h\u1ee3p l\u00fd s\u1ebd l\u00e0m gi\u1ea3m hi\u1ec7u su\u1ea5t.<\/li>\n\n\n\n<li>Khi pipeline v\u01b0\u1ee3t qu\u00e1 gi\u1edbi h\u1ea1n b\u1ed9 nh\u1edb 100MB m\u00e0 kh\u00f4ng s\u1eed d\u1ee5ng <code>allowDiskUse: true<\/code><\/li>\n<\/ul>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><em>\u0110\u1ecdc chi ti\u1ebft: <strong><a href=\"https:\/\/itviec.com\/blog\/huong-dan-su-dung-mongodb-find\/\" target=\"_blank\" rel=\"noreferrer noopener\">MongoDB find(): Chi\u1ebfc ch\u00eca kh\u00f3a \u201cv\u1ea1n n\u0103ng\u201d trong MongoDB<\/a><\/strong><\/em><\/p>\n<\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-aggregation-co-h\u1ed7-tr\u1ee3-song-song-parallel-processing-khong\"><strong>Aggregation c\u00f3 h\u1ed7 tr\u1ee3 song song (parallel processing) kh\u00f4ng?<\/strong><\/h3>\n\n\n\n<p>Aggregation trong MongoDB c\u00f3 h\u1ed7 tr\u1ee3 song song (parallel processing) th\u00f4ng qua t\u00ednh n\u0103ng sharding v\u00e0 parallelism trong m\u1ed9t s\u1ed1 stages nh\u1ea5t \u0111\u1ecbnh.<\/p>\n\n\n\n<p><strong>Sharded Clusters<\/strong>: Khi s\u1eed d\u1ee5ng MongoDB sharded clusters, MongoDB c\u00f3 th\u1ec3 ph\u00e2n t\u00e1n vi\u1ec7c th\u1ef1c thi aggregation qua c\u00e1c shard kh\u00e1c nhau trong cluster, gi\u00fap x\u1eed l\u00fd song song c\u00e1c ph\u1ea7n d\u1eef li\u1ec7u.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>C\u00e1c stage nh\u01b0 <code>$match<\/code>, <code>$project<\/code>, <code>$limit<\/code> c\u00f3 th\u1ec3 \u0111\u01b0\u1ee3c th\u1ef1c thi tr\u00ean t\u1eebng shard.\u00a0<\/li>\n\n\n\n<li>C\u00e1c stage nh\u01b0 <code>$group<\/code>, <code>$sort<\/code> c\u00f3 th\u1ec3 \u0111\u01b0\u1ee3c th\u1ef1c thi m\u1ed9t ph\u1ea7n tr\u00ean shard (partial aggregation) v\u00e0 merge k\u1ebft qu\u1ea3 tr\u00ean mongosh.<\/li>\n\n\n\n<li>M\u1ed7i shard s\u1ebd th\u1ef1c hi\u1ec7n c\u00e1c ph\u00e9p to\u00e1n tr\u00ean ph\u1ea7n d\u1eef li\u1ec7u c\u1ee7a n\u00f3, v\u00e0 MongoDB s\u1ebd g\u1ed9p k\u1ebft qu\u1ea3 l\u1ea1i \u0111\u1ec3 tr\u1ea3 v\u1ec1 cho ng\u01b0\u1eddi d\u00f9ng.<\/li>\n<\/ul>\n\n\n\n<p><strong>Parallel Execution<\/strong>: Trong m\u1ed9t s\u1ed1 tr\u01b0\u1eddng h\u1ee3p, MongoDB c\u00f3 th\u1ec3 th\u1ef1c hi\u1ec7n parallel execution ngay c\u1ea3 trong c\u00e1c stages nh\u01b0 <code>$group<\/code> ho\u1eb7c <code>$sort<\/code> n\u1ebfu d\u1eef li\u1ec7u \u0111\u01b0\u1ee3c chia \u0111\u1ec1u qua c\u00e1c shard. \u0110i\u1ec1u n\u00e0y gi\u00fap MongoDB t\u0103ng hi\u1ec7u su\u1ea5t khi l\u00e0m vi\u1ec7c v\u1edbi c\u00e1c t\u1eadp d\u1eef li\u1ec7u l\u1edbn.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-khi-nao-nen-can-nh\u1eafc-chia-nh\u1ecf-pipeline-ho\u1eb7c-dung-mapreduce\"><strong>Khi n\u00e0o n\u00ean c\u00e2n nh\u1eafc chia nh\u1ecf pipeline ho\u1eb7c d\u00f9ng MapReduce?<\/strong><\/h3>\n\n\n\n<p>Chia nh\u1ecf pipeline khi:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Khi pipeline qu\u00e1 ph\u1ee9c t\u1ea1p ho\u1eb7c qu\u00e1 d\u00e0i:<\/strong> N\u1ebfu pipeline c\u1ee7a b\u1ea1n c\u00f3 qu\u00e1 nhi\u1ec1u giai \u0111o\u1ea1n (th\u01b0\u1eddng > 20-30 stages) ho\u1eb7c c\u00e1c giai \u0111o\u1ea1n qu\u00e1 ph\u1ee9c t\u1ea1p, MongoDB c\u00f3 th\u1ec3 g\u1eb7p kh\u00f3 kh\u0103n trong vi\u1ec7c th\u1ef1c thi hi\u1ec7u qu\u1ea3. B\u1ea1n c\u00f3 th\u1ec3 chia nh\u1ecf pipeline th\u00e0nh c\u00e1c ph\u1ea7n x\u1eed l\u00fd \u0111\u1ed9c l\u1eadp v\u00e0 s\u1eed d\u1ee5ng <code>$out<\/code> ho\u1eb7c <code>$merge<\/code> \u0111\u1ec3 l\u01b0u k\u1ebft qu\u1ea3 trung gian..<\/li>\n\n\n\n<li><strong>Khi c\u1ea7n t\u1ed1i \u01b0u h\u00f3a b\u1ed9 nh\u1edb v\u00e0 t\u00e0i nguy\u00ean:<\/strong> N\u1ebfu d\u1eef li\u1ec7u qu\u00e1 l\u1edbn v\u00e0 kh\u00f4ng th\u1ec3 x\u1eed l\u00fd h\u1ebft trong b\u1ed9 nh\u1edb, b\u1ea1n c\u00f3 th\u1ec3 chia nh\u1ecf pipeline \u0111\u1ec3 x\u1eed l\u00fd t\u1eebng ph\u1ea7n d\u1eef li\u1ec7u m\u1ed9t c\u00e1ch hi\u1ec7u qu\u1ea3 h\u01a1n.<\/li>\n<\/ul>\n\n\n\n<p>S\u1eed d\u1ee5ng MapReduce khi:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Khi c\u1ea7n x\u1eed l\u00fd d\u1eef li\u1ec7u ph\u1ee9c t\u1ea1p h\u01a1n kh\u00f4ng h\u1ed7 tr\u1ee3 trong pipeline aggregation:<\/strong> <strong>MapReduce<\/strong> c\u00f3 th\u1ec3 \u0111\u01b0\u1ee3c s\u1eed d\u1ee5ng khi b\u1ea1n c\u1ea7n th\u1ef1c hi\u1ec7n c\u00e1c ph\u00e9p to\u00e1n ph\u1ee9c t\u1ea1p kh\u00f4ng th\u1ec3 th\u1ef1c hi\u1ec7n \u0111\u01b0\u1ee3c qua Aggregation Pipeline, ch\u1eb3ng h\u1ea1n nh\u01b0 khi c\u1ea7n s\u1ef1 linh ho\u1ea1t cao h\u01a1n trong vi\u1ec7c x\u1eed l\u00fd d\u1eef li\u1ec7u.<\/li>\n\n\n\n<li><strong>Khi d\u1eef li\u1ec7u kh\u00f4ng th\u1ec3 \u0111\u01b0\u1ee3c ph\u00e2n t\u00e1n hi\u1ec7u qu\u1ea3:<\/strong> Trong c\u00e1c tr\u01b0\u1eddng h\u1ee3p d\u1eef li\u1ec7u kh\u00f4ng d\u1ec5 d\u00e0ng chia th\u00e0nh c\u00e1c ph\u1ea7n nh\u1ecf (shards), MapReduce c\u00f3 th\u1ec3 x\u1eed l\u00fd \u0111\u01b0\u1ee3c nh\u1eefng t\u00ecnh hu\u1ed1ng n\u00e0y, m\u1eb7c d\u00f9 n\u00f3 \u00edt hi\u1ec7u qu\u1ea3 h\u01a1n so v\u1edbi Aggregation khi l\u00e0m vi\u1ec7c v\u1edbi d\u1eef li\u1ec7u \u0111\u00e3 \u0111\u01b0\u1ee3c ph\u00e2n t\u00e1n (sharded).<\/li>\n<\/ul>\n\n\n\n<p><strong>L\u01afU \u00dd:<\/strong> MapReduce \u0111\u00e3 b\u1ecb ng\u1eebng h\u1ed7 tr\u1ee3 t\u1eeb MongoDB phi\u00ean b\u1ea3n 5.0 tr\u1edf \u0111i v\u00e0 kh\u00f4ng c\u00f2n \u0111\u01b0\u1ee3c khuy\u1ebfn ngh\u1ecb s\u1eed d\u1ee5ng.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-n\u1ebfu-mapreduce-da-b\u1ecb-lo\u1ea1i-b\u1ecf-nen-dung-gi-thay-th\u1ebf\"><strong>N\u1ebfu MapReduce \u0111\u00e3 b\u1ecb lo\u1ea1i b\u1ecf, n\u00ean d\u00f9ng g\u00ec thay th\u1ebf?<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Aggregation Pipeline v\u1edbi <code>$accumulator<\/code> v\u00e0 <code>$function<\/code> (t\u1eeb MongoDB 4.4+) cho c\u00e1c logic ph\u1ee9c t\u1ea1p c\u1ea7n JavaScript.<\/li>\n\n\n\n<li><code>$merge<\/code> v\u00e0 <code>$out<\/code> \u0111\u1ec3 ghi k\u1ebft qu\u1ea3 v\u00e0o collection ho\u1eb7c x\u1eed l\u00fd d\u1eef li\u1ec7u theo batch.<\/li>\n\n\n\n<li>MongoDB Spark Connector ho\u1eb7c c\u00e1c ETL tools cho x\u1eed l\u00fd c\u00e1c kh\u1ed1i d\u1eef li\u1ec7u c\u1ef1c l\u1edbn.<\/li>\n\n\n\n<li>Change Streams k\u1ebft h\u1ee3p v\u1edbi application logic \u0111\u1ec3 x\u1eed l\u00fd d\u1eef li\u1ec7u real-time.<\/li>\n<\/ul>\n\n\n\n<p>V\u00ed d\u1ee5 c\u00e1ch d\u00f9ng Aggregation Pipeline k\u1ebft h\u1ee3p v\u1edbi <code>$function<\/code> \u0111\u1ec3 vi\u1ebft logic t\u00ednh to\u00e1n t\u00f9y ch\u1ec9nh b\u1eb1ng JavaScript nh\u01b0 sau:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>db.collection.aggregate(&#91;\n  {\n    $group: {\n      _id: \"$category\",\n      values: { $push: \"$value\" }\n    }\n  },\n  {\n    $addFields: {\n      customCalc: {\n        $function: {\n          body: function(values) {\n            \/\/ Custom JavaScript logic here\n            return values.reduce((a, b) => a + b * 2, 0);\n          },\n          args: &#91;\"$values\"],\n          lang: \"js\"\n        }\n      }\n    }\n  }\n])\n<\/code><\/pre>\n\n\n\n<p>Trong \u0111\u00f3 v\u00ed d\u1ee5 tr\u00ean th\u1ef1c hi\u1ec7n 2 b\u01b0\u1edbc ch\u00ednh:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>$group<\/code>: gom c\u00e1c document theo category, t\u1ea1o m\u1ea3ng values ch\u1ee9a to\u00e0n b\u1ed9 gi\u00e1 tr\u1ecb value.<\/li>\n\n\n\n<li><code>$function<\/code>: ch\u1ea1y \u0111o\u1ea1n JavaScript \u0111\u1ec3 x\u1eed l\u00fd m\u1ea3ng \u0111\u00f3, \u1edf \u0111\u00e2y l\u00e0 nh\u00e2n \u0111\u00f4i t\u1eebng gi\u00e1 tr\u1ecb r\u1ed3i c\u1ed9ng l\u1ea1i.<\/li>\n\n\n\n<li>K\u1ebft qu\u1ea3: m\u1ed7i nh\u00f3m c\u00f3 th\u00eam tr\u01b0\u1eddng <code>customCalc<\/code> th\u1ec3 hi\u1ec7n t\u1ed5ng \u0111\u00e3 t\u00ednh.<\/li>\n<\/ul>\n\n\n\n<p><strong>C\u00e1c gi\u1edbi h\u1ea1n quan tr\u1ecdng c\u1ee7a Aggregation Pipeline:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>Gi\u1edbi h\u1ea1n<\/strong><\/td><td><strong>M\u00f4 t\u1ea3<\/strong><\/td><td><strong>G\u1ee3i \u00fd kh\u1eafc ph\u1ee5c<\/strong><\/td><\/tr><tr><td>Document size limit<\/td><td>M\u1ed7i document t\u1ed1i \u0111a 16MB<\/td><td>Chia nh\u1ecf d\u1eef li\u1ec7u ho\u1eb7c d\u00f9ng $merge \u0111\u1ec3 ghi t\u1eebng ph\u1ea7n<\/td><\/tr><tr><td>Pipeline stage limit<\/td><td>T\u1ed1i \u0111a 1000 stages trong m\u1ed9t pipeline<\/td><td>G\u1ed9p logic ho\u1eb7c chia pipeline th\u00e0nh nhi\u1ec1u b\u01b0\u1edbc nh\u1ecf<\/td><\/tr><tr><td>Memory limit<\/td><td>M\u1ed7i stage ch\u1ec9 d\u00f9ng t\u1ed1i \u0111a 100MB RAM<\/td><td>D\u00f9ng t\u00f9y ch\u1ecdn allowDiskUse: true \u0111\u1ec3 cho ph\u00e9p ghi t\u1ea1m ra \u0111\u0129a<\/td><\/tr><tr><td>Time limit<\/td><td>Pipeline c\u00f3 th\u1ec3 b\u1ecb gi\u1edbi h\u1ea1n th\u1eddi gian ch\u1ea1y<\/td><td>D\u00f9ng maxTimeMS \u0111\u1ec3 \u0111\u1eb7t gi\u1edbi h\u1ea1n t\u00f9y \u00fd<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-t\u1ed5ng-k\u1ebft\"><span class=\"ez-toc-section\" id=\"Tong_ket\"><\/span><strong>T\u1ed5ng k\u1ebft<\/strong><span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p>Aggregation Pipeline l\u00e0 m\u1ed9t ph\u1ea7n kh\u00f4ng th\u1ec3 thi\u1ebfu trong MongoDB khi l\u00e0m vi\u1ec7c v\u1edbi c\u00e1c truy v\u1ea5n ph\u1ee9c t\u1ea1p v\u00e0 d\u1eef li\u1ec7u l\u1edbn. T\u1eeb l\u1ecdc d\u1eef li\u1ec7u \u0111\u1ebfn t\u00ednh to\u00e1n t\u1ed5ng h\u1ee3p, kh\u1ea3 n\u0103ng c\u1ee7a Aggregation gi\u00fap gi\u1ea3i quy\u1ebft nhi\u1ec1u b\u00e0i to\u00e1n m\u00e0 kh\u00f4ng c\u1ea7n ph\u1ea3i s\u1eed d\u1ee5ng \u0111\u1ebfn \u1ee9ng d\u1ee5ng b\u00ean ngo\u00e0i. Hi\u1ec3u r\u00f5 c\u00e1ch th\u1ee9c ho\u1ea1t \u0111\u1ed9ng c\u1ee7a Aggregation Pipeline kh\u00f4ng ch\u1ec9 gi\u00fap b\u1ea1n t\u1eadn d\u1ee5ng s\u1ee9c m\u1ea1nh c\u1ee7a MongoDB m\u00e0 c\u00f2n m\u1edf ra nhi\u1ec1u kh\u1ea3 n\u0103ng x\u1eed l\u00fd d\u1eef li\u1ec7u tr\u1ef1c ti\u1ebfp trong c\u01a1 s\u1edf d\u1eef li\u1ec7u, gi\u1ea3m thi\u1ec3u th\u1eddi gian v\u00e0 t\u00e0i nguy\u00ean cho c\u00e1c ph\u00e9p to\u00e1n ph\u1ee9c t\u1ea1p.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hi\u1ec7n nay, v\u1edbi s\u1ef1 gia t\u0103ng c\u1ee7a d\u1eef li\u1ec7u v\u00e0 y\u00eau c\u1ea7u v\u1ec1 t\u1ed1c \u0111\u1ed9 x\u1eed l\u00fd, c\u00e1c c\u00f4ng c\u1ee5 c\u01a1 s\u1edf d\u1eef li\u1ec7u nh\u01b0 MongoDB ng\u00e0y c\u00e0ng tr\u1edf n\u00ean quan tr\u1ecdng. Nh\u01b0ng ch\u1ec9 l\u01b0u tr\u1eef t\u1ed1t th\u00f4i ch\u01b0a \u0111\u1ee7, vi\u1ec7c t\u1ed1i \u01b0u h\u00f3a c\u00e1c truy v\u1ea5n m\u1edbi l\u00e0 y\u1ebfu t\u1ed1 then ch\u1ed1t \u0111\u1ec3 \u0111\u1ea3m [&hellip;]<\/p>\n","protected":false},"author":209,"featured_media":93337,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_gspb_post_css":"","footnotes":""},"categories":[10353,109,7226],"tags":[],"class_list":["post-93333","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai-data","category-chuyen-mon-it","category-database"],"blocksy_meta":[],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.8 (Yoast SEO v27.8) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Aggregate trong MongoDB: C\u00e1ch c\u1ea3i thi\u1ec7n hi\u1ec7u su\u1ea5t truy v\u1ea5n - ITviec Blog<\/title>\n<meta name=\"description\" content=\"Kh\u00e1m ph\u00e1 c\u00e1ch t\u1ed1i \u01b0u h\u00f3a Aggregate trong MongoDB \u0111\u1ec3 n\u00e2ng cao hi\u1ec7u su\u1ea5t truy v\u1ea5n v\u00e0 x\u1eed l\u00fd d\u1eef li\u1ec7u hi\u1ec7u qu\u1ea3.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/\" \/>\n<meta property=\"og:locale\" content=\"vi_VN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Aggregate trong MongoDB: C\u00e1ch c\u1ea3i thi\u1ec7n hi\u1ec7u su\u1ea5t truy v\u1ea5n\" \/>\n<meta property=\"og:description\" content=\"Hi\u1ec7n nay, v\u1edbi s\u1ef1 gia t\u0103ng c\u1ee7a d\u1eef li\u1ec7u v\u00e0 y\u00eau c\u1ea7u v\u1ec1 t\u1ed1c \u0111\u1ed9 x\u1eed l\u00fd, c\u00e1c c\u00f4ng c\u1ee5 c\u01a1 s\u1edf d\u1eef li\u1ec7u nh\u01b0 MongoDB ng\u00e0y c\u00e0ng tr\u1edf n\u00ean quan tr\u1ecdng. Nh\u01b0ng ch\u1ec9 l\u01b0u tr\u1eef\" \/>\n<meta property=\"og:url\" content=\"https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/\" \/>\n<meta property=\"og:site_name\" content=\"ITviec Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/ITviec\" \/>\n<meta property=\"article:published_time\" content=\"2025-11-28T16:42:27+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-12-10T07:16:27+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/itviec.com\/blog\/wp-content\/uploads\/2025\/11\/Aggregate-trong-MongoDB-scaled.png\" \/>\n\t<meta property=\"og:image:width\" content=\"800\" \/>\n\t<meta property=\"og:image:height\" content=\"421\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"M\u1ef9 Duy\u00ean\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@ITviec\" \/>\n<meta name=\"twitter:site\" content=\"@ITviec\" \/>\n<meta name=\"twitter:label1\" content=\"\u0110\u01b0\u1ee3c vi\u1ebft b\u1edfi\" \/>\n\t<meta name=\"twitter:data1\" content=\"M\u1ef9 Duy\u00ean\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u01af\u1edbc t\u00ednh th\u1eddi gian \u0111\u1ecdc\" \/>\n\t<meta name=\"twitter:data2\" content=\"19 ph\u00fat\" \/>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Aggregate trong MongoDB: C\u00e1ch c\u1ea3i thi\u1ec7n hi\u1ec7u su\u1ea5t truy v\u1ea5n - ITviec Blog","description":"Kh\u00e1m ph\u00e1 c\u00e1ch t\u1ed1i \u01b0u h\u00f3a Aggregate trong MongoDB \u0111\u1ec3 n\u00e2ng cao hi\u1ec7u su\u1ea5t truy v\u1ea5n v\u00e0 x\u1eed l\u00fd d\u1eef li\u1ec7u hi\u1ec7u qu\u1ea3.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/","og_locale":"vi_VN","og_type":"article","og_title":"Aggregate trong MongoDB: C\u00e1ch c\u1ea3i thi\u1ec7n hi\u1ec7u su\u1ea5t truy v\u1ea5n","og_description":"Hi\u1ec7n nay, v\u1edbi s\u1ef1 gia t\u0103ng c\u1ee7a d\u1eef li\u1ec7u v\u00e0 y\u00eau c\u1ea7u v\u1ec1 t\u1ed1c \u0111\u1ed9 x\u1eed l\u00fd, c\u00e1c c\u00f4ng c\u1ee5 c\u01a1 s\u1edf d\u1eef li\u1ec7u nh\u01b0 MongoDB ng\u00e0y c\u00e0ng tr\u1edf n\u00ean quan tr\u1ecdng. Nh\u01b0ng ch\u1ec9 l\u01b0u tr\u1eef","og_url":"https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/","og_site_name":"ITviec Blog","article_publisher":"https:\/\/www.facebook.com\/ITviec","article_published_time":"2025-11-28T16:42:27+00:00","article_modified_time":"2025-12-10T07:16:27+00:00","og_image":[{"width":800,"height":421,"url":"https:\/\/itviec.com\/blog\/wp-content\/uploads\/2025\/11\/Aggregate-trong-MongoDB-scaled.png","type":"image\/png"}],"author":"M\u1ef9 Duy\u00ean","twitter_card":"summary_large_image","twitter_creator":"@ITviec","twitter_site":"@ITviec","twitter_misc":{"\u0110\u01b0\u1ee3c vi\u1ebft b\u1edfi":"M\u1ef9 Duy\u00ean","\u01af\u1edbc t\u00ednh th\u1eddi gian \u0111\u1ecdc":"19 ph\u00fat"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/#article","isPartOf":{"@id":"https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/"},"author":{"name":"M\u1ef9 Duy\u00ean","@id":"https:\/\/itviec.com\/blog\/#\/schema\/person\/73733c0725c7e39e696a896bd1abe2d7"},"headline":"Aggregate trong MongoDB: C\u00e1ch c\u1ea3i thi\u1ec7n hi\u1ec7u su\u1ea5t truy v\u1ea5n","datePublished":"2025-11-28T16:42:27+00:00","dateModified":"2025-12-10T07:16:27+00:00","mainEntityOfPage":{"@id":"https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/"},"wordCount":4879,"publisher":{"@id":"https:\/\/itviec.com\/blog\/#organization"},"image":{"@id":"https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/#primaryimage"},"thumbnailUrl":"https:\/\/itviec.com\/blog\/wp-content\/uploads\/2025\/11\/Aggregate-trong-MongoDB-scaled.png","articleSection":["AI &amp; Data","Chuy\u00ean m\u00f4n IT","Database"],"inLanguage":"vi"},{"@type":"WebPage","@id":"https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/","url":"https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/","name":"Aggregate trong MongoDB: C\u00e1ch c\u1ea3i thi\u1ec7n hi\u1ec7u su\u1ea5t truy v\u1ea5n - ITviec Blog","isPartOf":{"@id":"https:\/\/itviec.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/#primaryimage"},"image":{"@id":"https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/#primaryimage"},"thumbnailUrl":"https:\/\/itviec.com\/blog\/wp-content\/uploads\/2025\/11\/Aggregate-trong-MongoDB-scaled.png","datePublished":"2025-11-28T16:42:27+00:00","dateModified":"2025-12-10T07:16:27+00:00","description":"Kh\u00e1m ph\u00e1 c\u00e1ch t\u1ed1i \u01b0u h\u00f3a Aggregate trong MongoDB \u0111\u1ec3 n\u00e2ng cao hi\u1ec7u su\u1ea5t truy v\u1ea5n v\u00e0 x\u1eed l\u00fd d\u1eef li\u1ec7u hi\u1ec7u qu\u1ea3.","breadcrumb":{"@id":"https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/#breadcrumb"},"inLanguage":"vi","potentialAction":[{"@type":"ReadAction","target":["https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/"]}]},{"@type":"ImageObject","inLanguage":"vi","@id":"https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/#primaryimage","url":"https:\/\/itviec.com\/blog\/wp-content\/uploads\/2025\/11\/Aggregate-trong-MongoDB-scaled.png","contentUrl":"https:\/\/itviec.com\/blog\/wp-content\/uploads\/2025\/11\/Aggregate-trong-MongoDB-scaled.png","width":800,"height":421,"caption":"Aggregate trong MongoDB - itviec blog"},{"@type":"BreadcrumbList","@id":"https:\/\/itviec.com\/blog\/aggregate-trong-mongodb\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"AI &amp; Data","item":"https:\/\/itviec.com\/blog\/ai-data\/"},{"@type":"ListItem","position":2,"name":"Aggregate trong MongoDB: C\u00e1ch c\u1ea3i thi\u1ec7n hi\u1ec7u su\u1ea5t truy v\u1ea5n"}]},{"@type":"WebSite","@id":"https:\/\/itviec.com\/blog\/#website","url":"https:\/\/itviec.com\/blog\/","name":"ITviec Blog","description":"IT Jobs &amp; People in Vietnam","publisher":{"@id":"https:\/\/itviec.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/itviec.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"vi"},{"@type":"Organization","@id":"https:\/\/itviec.com\/blog\/#organization","name":"ITviec","url":"https:\/\/itviec.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"vi","@id":"https:\/\/itviec.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/itviec.com\/blog\/wp-content\/uploads\/2018\/12\/itviec-black-square-facebook.png","contentUrl":"https:\/\/itviec.com\/blog\/wp-content\/uploads\/2018\/12\/itviec-black-square-facebook.png","width":1800,"height":1800,"caption":"ITviec"},"image":{"@id":"https:\/\/itviec.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/ITviec","https:\/\/x.com\/ITviec","https:\/\/www.linkedin.com\/company\/itviec","https:\/\/www.youtube.com\/channel\/UCYthAQ3bcGr57M_ag5gHDvQ"]},{"@type":"Person","@id":"https:\/\/itviec.com\/blog\/#\/schema\/person\/73733c0725c7e39e696a896bd1abe2d7","name":"M\u1ef9 Duy\u00ean","image":{"@type":"ImageObject","inLanguage":"vi","@id":"https:\/\/itviec.com\/blog\/wp-content\/uploads\/2024\/03\/Author_Duyen-Tran-120x120.jpg","url":"https:\/\/itviec.com\/blog\/wp-content\/uploads\/2024\/03\/Author_Duyen-Tran-120x120.jpg","contentUrl":"https:\/\/itviec.com\/blog\/wp-content\/uploads\/2024\/03\/Author_Duyen-Tran-120x120.jpg","caption":"M\u1ef9 Duy\u00ean"},"url":"https:\/\/itviec.com\/blog\/author\/my-duyen\/"}]}},"_links":{"self":[{"href":"https:\/\/itviec.com\/blog\/wp-json\/wp\/v2\/posts\/93333","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/itviec.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/itviec.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/itviec.com\/blog\/wp-json\/wp\/v2\/users\/209"}],"replies":[{"embeddable":true,"href":"https:\/\/itviec.com\/blog\/wp-json\/wp\/v2\/comments?post=93333"}],"version-history":[{"count":3,"href":"https:\/\/itviec.com\/blog\/wp-json\/wp\/v2\/posts\/93333\/revisions"}],"predecessor-version":[{"id":93339,"href":"https:\/\/itviec.com\/blog\/wp-json\/wp\/v2\/posts\/93333\/revisions\/93339"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/itviec.com\/blog\/wp-json\/wp\/v2\/media\/93337"}],"wp:attachment":[{"href":"https:\/\/itviec.com\/blog\/wp-json\/wp\/v2\/media?parent=93333"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itviec.com\/blog\/wp-json\/wp\/v2\/categories?post=93333"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itviec.com\/blog\/wp-json\/wp\/v2\/tags?post=93333"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}