看了這麽多天的文章,是否覺得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 }
老師想了幾種加分方式
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.隔壁小王考太高分了,加分完超過總分,老師你還是選第一種加分方法(•̀ᴗ• )
本篇文章同步放在我的部落格,大家有空可以進來逛逛