今天繼續昨天的主題,講解陣列操作符的部分,比較不一樣的是今天用來舉例的陣列資料,會比昨天在複雜一點,同時也會用比較多不一樣的範例,來講解不同的的與法,因為每種語法適用的場景比較不一樣。
假設:我們現在考試資訊的collection,專門紀錄每一科考試學生的平均分數、應考人數、考試日期,資料的形式是陣列內再包一層陣列,第二層陣列只會有兩個item,資料格式如下。
{
_id: 1,
english: [
["student", 52],
["avg", 98],
["data", "2022-07-19T02:59:50.714Z"]
]
}
如果我們這時要做資料型態的轉換,將陣列轉換成物件,可以使用$arrayToObject
這個指定,後面接要轉換的陣列。轉變的規則會是,第二層陣列第一個item會被當成物件的key值,第二個item會被當成物件的value值。
test.aggregate([
{
$project: {
english: { $arrayToObject: "$english" }
}
}
]);
// 最後回傳的資料
{
_id: 1,
english: { student: 52, avg: 98, data: '2022-07-19T02:59:50.714Z' }
}
ps.如果想要將物件轉變成陣列,可以改用$objectToArray
。
第二個範例要來介紹,如何對陣列資料進行排序。
例如:我們現在英文的成績是寫在陣列內,裡面除了成績,還有紀錄學生的姓名,資料如下。
{
_id: 1,
english: [
{ name: "小明", score: 88 },
{ name: "小王", score: 46 },
{ name: "小美", score: 90 }
]
}
我們希望可以按照成績(sort)進行排序,這時可以使用以下指令。
test.aggregate([
{
$project: {
english: {
$sortArray: {
input: "$english", // 要進行排序的陣列
sortBy: { score: 1 } // 要透過陣列中哪一個值進行排序,1或-1用來決定排序方向
}
}
}
}
]);
// 最後回傳的資料
{
_id: 1,
english: [
{ name: "小王", score: 46 },
{ name: "小明", score: 88 },
{ name: "小美", score: 90 }
]
}
延續上面範例的資料,如果我們想幫每位學生的英文成績,都加10分,這時候可以使用$map
,它和JS的Array.prototype.map()語法是一樣的概念,可以操作陣列每一個元素,轉換成我們想要的資料,並且回傳一個新的陣列。
test.aggregate([
{
$project: {
english: {
$map: {
input: "$english", // 要操作的陣列
as: "item", // 宣告一個變數名稱,代表陣列每一個item
in: { // 最後回傳的陣列item
name: "$$item.name",
score: { $add: ["$$item.score", 10] }
}
}
}
}
}
// 最後回傳的資料
{
_id: 1,
english: [
{ name: "小王", score: 56 },
{ name: "小明", score: 98 },
{ name: "小美", score: 100 }
]
}
不得不說陣列相關的操作符還真多,剩下五個明天繼續 (๑•̀ㅂ•́)و✧
本篇文章同步放在我的部落格,大家有空可以進來逛逛