於ROBO 3T的shell中使用js搭配mongodb語法,來分析學生的成績(國文、英文、數學、理化、社會),實作以下內容:
- 亂數產生全班39個學生的成績
- 全班各科的平均計算
- 學生個別成績總和及平均
- 各成績級距人數統計
Robo 3T工具的介紹,可點擊以下圖片連結
新增本範例所需Collection,執行以下語法:
db.createCollection('ClassGrade'); //全班成績
db.createCollection('SubjectScoreRange'); //各科成績級距人數統計
隨機產生40筆學生的成績單資料,語法如下:
var names = ['許○榮','陳○翔','徐○傑','翁○暉','賴○方','林○涵','商○文','楊○安','王○閔','陳○信','蔡○哲','李○達','傅○成','陳○安','林○廷','洪○丞','陳○宇','曹○','劉○賢','蔡○豪','林○雅','李○寧','萬○華','蔡○珊','潘○雯','周○婕','羅○汶','傅○瑩','古○云','賴○靜','周○秀','杜○樺','周○惠','吳○宜','熊○馨','陳○全','羅○馨','宋○頤','林○緯',]
for(var i = 0; i < names.length; i++)
{
db.ClassGrade.insert(
{
Name: names[i],
Chinese: NumberInt(_rand() * 100),
English: NumberInt(_rand() * 100),
Math: NumberInt(_rand() * 100),
Science: NumberInt(_rand() * 100),
Sociology: NumberInt(_rand() * 100)
}
)
}
檢查新增狀況:
db.ClassGrade.find()
執行結果:
計算直向的平均值(全班平均):採個別變數撈出並print出來
var SubjectAvgArray = db.ClassGrade.aggregate([
{
$group:{
_id: {}, //null set
Chinese_average :{
$avg : '$Chinese'
},
Math_average :{
$avg : '$Math'
},
English_average :{
$avg: '$English'
},
Science_average :{
$avg: '$Science'
},
Sociology_average :{
$avg: '$Sociology'
}
}
}
]).toArray();
var print_message = "==========全班平均==========\n";
print_message += '國文:' + SubjectAvgArray[0].Chinese_average + "\n";
print_message += '數學:' + SubjectAvgArray[0].Math_average + "\n";
print_message += '英語:' + SubjectAvgArray[0].English_average + "\n";
print_message += '理化:' + SubjectAvgArray[0].Science_average+ "\n";
print_message += '社會:' + SubjectAvgArray[0].Sociology_average+ "\n";
print(print_message);
執行結果:
製作學生個別成績加總及平均:使用$add 及 $divide,產生新的計算結果欄位
db.ClassGrade.aggregate([
{
$project:{
score_total :{
$add:['$Chinese','$Math','$English','$Science','$Sociology']
},
score_average :{
$divide:[{$add:['$Chinese','$Math','$English','$Science','$Sociology']},5]
}
}
}
]);
執行結果:
使用mongodb語法來撈取ClassGrade Collection中Chinese欄位介於0與9之間的總數量,如下:
var chi0to9_count = db.ClassGrade.find({
'Chinese' :
{
$gte : 0, //Great Then Equal
$lte : 9 //Less Then Equal
}
}).count();
print(chi0to9_count);
若成功顯示,則將上述程式碼加入JS語法作加工,將成績單資料依照各別科目做區間統計,並將計算結果加入新的Collection(SubjectScoreRange)中,語法如下。
var range_array = [];
range_array.push([0,0]); //0
range_array.push([1,9]); //1-9
range_array.push([10,19]); //10-19
range_array.push([20,29]); //20-29
range_array.push([30,39]); //30-39
range_array.push([40,49]); //40-49
range_array.push([60,69]); //60-69
range_array.push([70,79]); //70-79
range_array.push([80,89]); //80-89
range_array.push([90,99]); //90-99
range_array.push([100,100]); //100
//延伸閱讀: Collection All Attribute's Name
//https://stackoverflow.com/questions/2298870/get-names-of-all-keys-in-the-collection
var subject_array = ['Chinese','English','Math','Science','Sociology'];
var searchObj;
var chi_count_array = new Array(range_array.length);
db.SubjectScoreRange.remove({}); //remove all
var range_item_name;
for(var i = 0; i < range_array.length; i++)
{
searchObj =
{
$gte : range_array[i][0],
$lte : range_array[i][1]
};
if(range_array[i][0] == range_array[i][1])
range_item_name = range_array[i][0].toString(); //避免出現小數點
else
range_item_name = range_array[i][0] + '-' + range_array[i][1];
db.SubjectScoreRange.insert({
'Range' : range_item_name,
'Chinese' : db.ClassGrade.find({'Chinese': searchObj}).count().toString(),
'English' : db.ClassGrade.find({'English': searchObj}).count().toString(),
'Math' : db.ClassGrade.find({'Math': searchObj}).count().toString(),
'Science' : db.ClassGrade.find({'Science': searchObj}).count().toString(),
'Sociology' : db.ClassGrade.find({'English': searchObj}).count().toString(),
});
}
檢視統計結果,語法如下:
db.getCollection('SubjectScoreRange').find({})
執行結果:
聚合(Aggregate)存取參考來源:
https://www.runoob.com/mongodb/mongodb-aggregate.html
https://stackoverflow.com/questions/29342506/what-is-the-return-type-of-aggregate-method-in-mongodb