iT邦幫忙

2022 iThome 鐵人賽

DAY 14
0
自我挑戰組

被MongoDB用Aggregate暴打的後端小菜雞日記系列 第 14

被MongoDB用Aggregate暴打的後端小菜雞日記-day14-$facet 一次使用多個pipeline

  • 分享至 

  • xImage
  •  

看了這麽多天的文章,是否覺得aggregate用來搜尋資料真的很好用,其實它另一個很神奇的用法$facet,可以讓你使用同一個collection的資料,但是分別使用不同的pipeline算法,得出不同的結果出來。

例如:現在有好幾筆學生成績資料,老師認爲這次段考大家成績考的不是很理想,想要幫大家加分,但又不知道哪一種加分方式比較好,這時候就可以用$facet算出不同結果看看。

學生資料如下

  { _id: 1, name: " 小美", math: 20, english: 12 },
  { _id: 2, name: " 小王", math: 86, english: 75 },
  { _id: 3, name: " 小明", math: 78, english: 30 },
  { _id: 4, name: " 小帥", math: 80, english: 60 },
  { _id: 5, name: " 小真", math: 78, english: 12 }

老師想了幾種加分方式

  1. 大家的總分都加30分
  2. 普遍英文大家都考的比較不好,英文的分數乘上1.5
  3. 數學成績乘上1.2,英文的分數乘上1.5,讓分數更好看一點

ps.乘完分數是小數會被無條件捨去

這時可以使用以下指令做計算

student.aggregate([
  {
    $facet: {
      // 第一種pipeline算法
      "first_count": [
        { $project: { name: 1, total: { $add: ["$math", "$english", 30] } } }
      ],
      // 第二種pipeline算法
      "second_count": [
        {
          $addFields: {
            english: { $floor: { $multiply: ["$english", 1.5] } }
          }
        },
        { $project: { name: 1, total: { $add: ["$math", "$english"] } } }
      ],
      // 第三種pipeline算法
      "third_count": [
        {
          $addFields: {
            math: { $floor: { $multiply: ["$math", 1.2] } },
            english: { $floor: { $multiply: ["$english", 1.5] } }
          }
        },
        { $project: { name: 1, total: { $add: ["$math", "$english"] } } }
      ]
    }
  }
]);

$facet語法其實很簡單,後面接一個物件,key要填回傳資料的欄位名稱,value會是一個陣列,裡面寫aggregate pipeline的語法,和之前寫的都類似。

另外就是$floor這個操作符,能夠將小數無條件捨去成整數,遇到有小數的欄位需要換成整數,還蠻好用的。

最後會回傳以下資料,可以讓老師選擇要哪種加分方式比較好

{
  first_count: [
    { _id: 1, name: " 小美", total: 62 },
    { _id: 2, name: " 小王", total: 191 },
    { _id: 3, name: " 小明", total: 138 },
    { _id: 4, name: " 小帥", total: 170 },
    { _id: 5, name: " 小真", total: 120 }
  ],
  second_count: [
    { _id: 1, name: " 小美", total: 38 },
    { _id: 2, name: " 小王", total: 198 },
    { _id: 3, name: " 小明", total: 123 },
    { _id: 4, name: " 小帥", total: 170 },
    { _id: 5, name: " 小真", total: 98 }
  ],
  third_count: [
    { _id: 1, name: " 小美", total: 52 },
    { _id: 2, name: " 小王", total: 215 },
    { _id: 3, name: " 小明", total: 138 },
    { _id: 4, name: " 小帥", total: 186 },
    { _id: 5, name: " 小真", total: 111 }
  ]
}

ps.隔壁小王考太高分了,加分完超過總分,老師你還是選第一種加分方法(•̀ᴗ• )

本篇文章同步放在我的部落格,大家有空可以進來逛逛


上一篇
被MongoDB用Aggregate暴打的後端小菜雞日記-day13-$bucket 桶子分組
下一篇
被MongoDB用Aggregate暴打的後端小菜雞日記-day15-$merge 將資料寫回資料庫
系列文
被MongoDB用Aggregate暴打的後端小菜雞日記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言