一、生成学生信息脚本
利用该脚本可以生成任意个学生信息,包括学号、姓名、班级、年级、专业、课程名称、课程成绩等信息,此处生成2万名学生,学生所有信息都是给定范围后随机生成。
生成学生信息后,再来对学生信息进行简单查询。
- 主函数
函数的说明:generateStudents(生成学生的人数,年级,是否覆盖之前的值,是否分片),运行完程序后,会生成2w名学生信息
// 主程序从这里开始
generateStudents(10000,2022,true,false);//overwrite=true 1000个学生,2018级
generateStudents(10000,2021,false,false);
- 生成学生数据
默认有四个参数,生成100个学生信息,年级是2020,覆盖掉之前的文档,分片
function generateStudents(snum=100, sgrade=2020, overwrite=true, sharding=true) {db = db.getSiblingDB("cqust"); // use cqust;创建数据库if (sharding) {sh.enableSharding("cqust");}if (overwrite) {db.getCollection("students").drop();// 等价于db.students.drop() 删除students集合if (sharding)sh.shardCollection("cqust.students",{"sno":"hashed"});}for(var i=0; i<snum/100; i++){//创建snum个学生,每100个作为一批,太多可能影响效率var StudentsDoc = new Array();for(var j=0; j<100; j++){var sid = sgrade*1e6+i*100+j;//定义变量var sname = getRandName();var gender = Math.floor(Math.random()*2);var phone = getRandPhone();var major = getRandMajor();var height = Math.floor(Math.random()*30+gender*5+150);var weight = Math.floor(Math.random()*30+gender*20+40);var sclass = Math.floor(Math.random()*4+1);var courses = new Array();for(var k=0; k<Math.floor(Math.random()*5);k++){var course_credit = getRandCourse();courses[k] = {"course":course_credit[0], "credit":course_credit[1], "score":Math.floor(Math.random()*50)+50};}StudentsDoc[j] = {"sno":sid,"name":sname, "gender":gender, // "height":height, // "weight":weight,"body":{"height":height, "weight":weight},//嵌入文档"list":[Math.ceil(Math.random()*6),Math.ceil(Math.random()*6),Math.ceil(Math.random()*6)],//三个随机数1-6"phone":phone, "role":"student", "major": major,"grade": sgrade, "class": sclass, "courses":courses};}db.getCollection("students").insertMany(StudentsDoc);// db.students.insertMany(StudentsDoc) 如果是1000个学生信息,插入10次,一次100}
}
在该程序中,【Math.random(): 生成一个 [0, 1) 之间的随机小数(包括 0,不包括 1)。Math.random() * 6: 将随机数放大到 [0, 6) 的范围。Math.ceil(): 将上述结果向上取整,形成一个范围 [1, 6] 的整数(只有 1 到 6 这六个数能被生成)。重复三次:为了生成三个随机数,将 Math.ceil(Math.random() * 6) 这一段复制了三次,形成了一个包含这三个随机数的数组】
3. 生成随机手机号
function getRandPhone(){//手机开头3位数var heads = ["134","138","139","150","151","152","157","158","159","170","189"];//举例:0.5x11=5.5向下取整等于5,取heads[5]var phone = heads[Math.floor(Math.random()*heads.length)];var numbers = [1,2,3,4,5,6,7,8,9];for(var i=0; i<8; i++){phone+=numbers[Math.floor(Math.random()*numbers.length)];}return phone;
}
在该函数中,Math.random() 生成一个 [0, 1) 的随机数,通过乘以 heads.length 来得到一个适合数组索引的随机数。Math.floor 将其向下取整,确保得到一个有效的数组索引。
导入方式:
- 命令行方式
mongo .\GenerateStudents.js
mongo .\GenerateStudents.js --shell
(加了--shell运行完毕后,直接进入shell里面)
show dbs
db.students.find().pretty()//方便显示
- Navicat查询方式(直接将代码复制到查询中运行即可)
在网格视图中,红色类型为字符串类型,右对齐是数值类型,如果需要展开,这种点操作符说明是嵌入文档
二、简单查询操作
- 查询身高170以上的学生
use cqust;
// 查询身高170以上的学生
//"body": {
// "height": 179,
// "weight": 62
// },
var 查询条件 = {"body.height":{$gt:170}};
var 查询条件 = {"body.height":170};
// var 查询条件 = {body.height:170};// 字段名中有.和$, 不打引号要报错
var 返回字段 = {};
db.students.find(查询条件,返回字段);
- 身高小于160,体重大于60
// 身高小于160,体重大于60
//写法一:
var 查询条件 = {"body.height":{$lt:160}, "body.weight":{$gt:60}};
var 返回字段 = {};
db.students.find(查询条件,返回字段);
//写法二:
var 查询条件1 = {"body.height":{$lt:160}};
var 查询条件2 = {"body.weight":{$gt:60}};
var 查询条件 = {$and:[查询条件1,查询条件2]};//逻辑运算符后面必须加数组
var 返回字段 = {};
db.students.find(查询条件,返回字段);
- 列表字段查询
//列表字段查询
// "list": [
// 6,
// 2,
// 1
// ]
var 查询条件1 = {"list":[4,5,6]}; // 值是数组,且完全匹配列表元素数量, 顺序不能变
var 查询条件e = {"list":[4,5]}; // 错误,值是数组,不完全匹配,查不到
//只匹配两个元素,需要用到数组查询运算符$all
var 查询条件2 = {"list":{$all:[4,5]}}; // 值是列表,元素数量完全匹配,顺序可以变
var 查询条件3 = {"list":6}; // 任意包含6的数组都查到
db.students.find(查询条件)
- 查询"数据导入与预处理应用"不及格的学生
//"courses": [
// {
// "course": "大数据分析与内存计算",
// "credit": 4,
// "score": 56
// },
// {
// "course": "数据导入与预处理应用",
// "credit": 4,
// "score": 82
// }
// ]
// 查询"数据导入与预处理应用"不及格的学生【数组中的元素查询,结果不对】
var 查询条件 = {"courses.course":"数据导入与预处理应用","courses.score":{$lt:60}};
var 返回字段 = {};
db.students.find(查询条件,返回字段);
直接查询结果不对,因为在数组中,存在多个元素对应同一个字段条件,会使查询不能对应到元素内部。
加了$elemMatch后查询结果正确。
// 所以用$elemMatch可以在元素内进行匹配
var 查询条件 = {"courses":{$elemMatch:{"course":"数据导入与预处理应用","score":{$lt:60}}}};
//查询条件或者写为json格式
var 查询条件 = {"courses":{$elemMatch:{"course": "数据导入与预处理应用","score": {$lt:60}}}
};
var 返回字段 = {};
db.students.find(查询条件,返回字段);
注意:$elemMatch后面的写法
- 查询"数据导入与预处理应用"不及格的学生的学号和姓名班级,不要_id
// select * from tbname;
// select field1,field2,field3... from tbname;
// 查询"数据导入与预处理应用"不及格的学生的学号和姓名班级,不要_id
var 查询条件 = {"courses":{$elemMatch:{"course":"数据导入与预处理应用","score":{$lt:60}}}};
// 返回字段 = {字段名:是否返回};
// 值是布尔值 (true|false -> 1|0 -> inclusion|exclusion)
var 返回字段 = {sno:true,name:1,major:1,grade:1,class:1,_id:0};
//var 返回字段 = {_id:0,body:0,list:0,gender:0,role:0,phone:0,courses:0};
db.students.find(查询条件,返回字段);
- 查询"数据导入与预处理应用"不及格的学生的除了courses和list以外的所有字段
// 查询"数据导入与预处理应用"不及格的学生的除了courses和list以外的所有字段
var 返回字段 = {courses:0,list:0};
db.students.find(查询条件,返回字段);// 嵌入文档中的字段也可以控制是否返回
var 返回字段 = {"courses.score":0};
db.students.find(查询条件,返回字段);var 返回字段 = {"list":{$slice:[0,1]}}; // [起点index,取几个] index从0开始
//var 返回字段 = {"list":{$slice:-2}}; // 取几个
db.students.find(查询条件,返回字段);
- 修改字段名
//改字段名:新字段名:$旧字段名 构造一个新字段,通过$取旧字段的值
//$ 取值的意思
var 查询条件 = {"courses":{$elemMatch:{"course":"数据导入与预处理应用","score":{$lt:60}}}};
var 返回字段 = {_id:0,学号:"$sno",姓名:"$name",年级:"$grade",专业:"$major",班号:"$class"};
db.students.find(查询条件,返回字段);
- 查询"数据导入与预处理应用"不及格的学生的学号、姓名、年级、班级,和数据导入与预处理应用课程的成绩,不要_id
// 查询"数据导入与预处理应用"不及格的学生的学号、姓名、年级、班级,和数据导入与预处理应用课程的成绩,不要_id
var 查询条件 = {"courses":{$elemMatch:{"course":"数据导入与预处理应用","score":{$lt:60}}}};
var 返回字段 = {_id:0,sno:1,name:1,grade:1,major:1,"courses.course":1,"courses.score":1};
db.students.find(查询条件,返回字段);
- 在上一步操作基础上,返回的成绩中,只显示"数据导入与预处理应用"课程
//在上一步操作基础上,返回的成绩中,只显示"数据导入与预处理应用"课程
var 查询条件 = {"courses":{$elemMatch:{"course":"数据导入与预处理应用","score":{$lt:60}}}};
// 使用elemMatch匹配数组字段中满足条件的
var 返回字段 =
{_id:0,sno:1,name:1,grade:1,major:1,"courses":{$elemMatch:{"course":"数据导入与预处理应用","score":{$lt:60}}}};
db.students.find(查询条件,返回字段);
课堂练习二:
1.利用GenerateStudents.js脚本生成2w个学生信息,并保存到mongodb中。
2.查询体重70及以上学生信息。
3.查询身高大于180,体重大于65学生信息。
4.查询"大数据概论"课程及格的学生。
5.查询"大数据概论"课程及格的学生中,除了courses和list意外的所有字段。