前言
最近在不断练习MongoDB的原生语句,包括了增删改查,分组,聚合等方面的练习,
也提供了完善了数据,以下的每一段语句都能直接复制到Navicate和MongoDB shell执行
主要是参考资料里老哥的题目跟着打了一遍,还后加了点东西
跟着敲一边基本都能熟悉一些基本的结构和方式
一、数据准备
首先数据生成
// school
// 数据生成 -新建1年级3个班的数据
for(grade_index in (grade = ['grade_1_1', 'grade_1_2', 'grade_1_3'])) {
for (var i = 1; i <= 10; i++) {
db[grade[grade_index]].insert({
"name": "zhangsan" + i,
"sex": Math.round(Math.random() * 10) % 2,
"age": Math.round(Math.random() * 6) + 3,
"hobby": []
});
}
}
二、查询练习
// ------------------------------------------------------------------------------------- 查询练习
// 查看一年级二班grade_1_2中所有年龄小于 4 岁并且大于 7 岁的学生
db.grade_1_2.find({$and: [{age: {$lt: 4}}, {age: {$gt: 7}}]})
// 查看一年级二班grade_1_2中所有年龄是 4 岁或 6 岁的学生
db.grade_1_2.find({$or: [{age:4}, {age:7}]})
// 查看一年级二班grade_1_2中所有姓名带zhangsan1的学生
db.grade_1_2.find({name: {$regex: "zhangsan1"}})
// 查看一年级二班grade_1_2中所有姓名带zhangsan1和zhangsan2的学生
db.grade_1_2.find({name: {
$in: [new RegExp("zhangsan1"), new RegExp("zhangsan4")]
}})
// 查看一年级二班grade_1_2中所有兴趣爱好有三项的学生 xxx
db.grade_1_2.find({"hobby": {"$size": 3}})
// 查看一年级二班`grade_1_2`中所有兴趣爱好包括画画的学生
db.grade_1_2.find({hobby: "draw"})
// 查看一年级二班`grade_1_2`中所有兴趣爱好既包括画画又包括跳舞的学生
db.grade_1_2.find({hobby: {$all: ["draw","dance"]}})
// 查看一年级二班grade_1_2中所有兴趣爱好有三项的学生的学生数目
db.grade_1_2.find({hobby: {$size: 3}}).count()
// 查看一年级二班的第二位学生
db.grade_1_2.find().skip(1).limit(1)
// 查看一年级二班的学生,按年纪升序
db.grade_1_2.find({}).sort({age: 1})
// 查看一年级二班的学生,按年纪降序
db.grade_1_2.find({}).sort({age: -1})
// 查看一年级二班的学生,年龄值有哪些
db.grade_1_2.distinct("age")
// 查看一年级二班的学生,兴趣覆盖范围有哪些
db.grade_1_2.distinct("hobby")
// 查看一年级二班的学生,男生(`sex`为 0)年龄值有哪些
db.grade_1_2.distinct("age", {sex:0})
三、删除练习
// ------------------------------------------------------------------------------------- 删除练习
// 一年级二班grade_1_2, 删除所有 4 岁的学生
db.grade_1_2.remove({age: 4})
// 一年级二班grade_1_2, 删除第一位 6 岁的学生
db.grade_1_2.remove({age: 6}, {justOne: 1})
四、修改/更新练习
// ------------------------------------------------------------------------------------- 修改练习
// 一年级二班grade_1_2中,修改名为zhangsan7的学生,年龄为 8 岁,兴趣爱好为 跳舞和画画;
db.grade_1_2.update({name: "zhangsan6"}, {$set: {age: 8, hobby: ["dance", "draw"]}})
// 一年级二班`grade_1_2`中,追加zhangsan7`学生兴趣爱好唱歌;
db.grade_1_2.update({name: "zhangsan6"}, {$push: {hobby: "sing"}})
// 一年级二班`grade_1_2`中,追加zhangsan7`学生兴趣爱好吹牛和打篮球;
db.grade_1_2.update({name: "zhangsan6"},{$push: {hobby: {$each: ["brag", "playbasketball"]}}})
// 一年级二班`grade_1_2`中,追加`zhangsan7`学生兴趣爱好唱歌和打篮球,要保证`hobby`数组不重复;
db.grade_1_2.update({name: "zhangsan7"}, {$addToSet: {hobby: {$each: ["draw1","draw"]}}})
// 新学年,给一年级二班所有学生的年龄都增加一岁
db.grade_1_2.update({},{$inc: {age:1}},{multi: true})
// 一年级二班grade_1_2中,删除zhangsan7学生的sex属性
db.grade_1_2.update({name: "zhangsan6"}, {$unset: {sex: 1}})
// 一年级二班grade_1_2中,删除zhangsan7学生的hobby数组中的头元素 1: 尾元素, -1: 头元素
db.grade_1_2.update({name: "zhangsan7"}, {$pop: {hobby: -1}})
// 一年级二班`grade_1_2`中,删除`zhangsan7`学生的`hobby`数组中的尾元素
db.grade_1_2.update({name: "zhangsan7"}, {$pop: {hobby: 1}})
// 一年级二班`grade_1_2`中,删除`zhangsan7`学生的`hobby`数组中的`sing`元素
db.grade_1_2.update({name: "zhangsan7"}, {$pull: {hobby: "sing1"}})
五、分组练习
这部分我跑不了,但是还是放出来
// ------------------------------------------------------------------------------------- 分组练习 ->> [Error] Error: no such command: 'group'
// 新建一个集合grade_1_4,记录一年级四班在期中考试时的成绩;
for (var i = 1; i <= 10; i++) {
db.grade_1_4.insert({
"name": "zhangsan" + i,
"sex": Math.round(Math.random() * 10) % 2,
"age": Math.round(Math.random() * 6) + 3,
"score": {
"chinese": 60 + Math.round(Math.random() * 40),
"math": 60 + Math.round(Math.random() * 40),
"english": 60 + Math.round(Math.random() * 40)
}
});
}
// 统计每名学生在考试中的总分
db.grade_1_4.group({
key: {name: 1},
cond: {},
reduce: function(curr, result){
result.total += curr.score.chinese + curr.score.math + curr.score.english;
},
initial: {total: 0}
})
// 统计每名男生在考试中的总分
db.grade_1_4.group({
key: {"name": 1},
cond: {"sex": 0},
reduce: function(curr, result) {
result.total += curr.score.chinese + curr.score.math + curr.score.english;
},
initial: { total : 0 }
})
// 统计每名男生在考试中的总分及平均分
db.grade_1_4.group({
key: {"name": 1},
cond: {"sex": 0},
reduce: function(curr, result) {
result.total += curr.score.chinese + curr.score.math + curr.score.english;
},
initial: { total : 0 },
finalize: function(item) {
item.avg = (item.total / 3).toFixed(2);
return item;
}
})
六、聚合练习
// ------------------------------------------------------------------------------------- 聚合练习
// 根据姓名分组, 并统计人数
db.grade_1_4.aggregate([
{$group: {_id: "$name", count: {$sum: 1}}}
])
// 根据姓名分组, 并统计人数,过滤人数大于 1 的学生
db.grade_1_4.aggregate([
{$group: {_id: "$name", numb: {$sum: 1}}},
{$match: {numb: {$lte: 1}}}
])
// 统计每名学生在考试中的总分
db.grade_1_4.aggregate([
{$group: {_id: "$name", score: {$sum: {$sum: ["$score.chinese","$score.math","$score.english"]}}}}
])
// 统计每名男生在考试中的总分
db.grade_1_4.aggregate([
{$match: {sex: 0}},
{$group: {_id: "$name", score: {$sum: {$sum: ["$score.chinese","$score.math","$score.english"]}}}}
])
// 统计每名男生在考试中的总分, 总分降序-1 升序1 $add不能在group中用, sum可以在project中使用
db.grade_1_4.aggregate([
{$match: {sex: 0}},
{$group: {_id: "$name", score: {$sum: {$sum: ["$score.chinese","$score.math","$score.english"]}}}},
{$sort: {score: -1}}
])
七、自定义练习
这部分就是我自己想了几个问题写了写
// ------------------------------------------------------------------------------------- 自定义练习
// 统计总共多少名学生
db.grade_1_4.aggregate([
{$group: {_id: null, total: {$sum: 1}}}
])
// 获取语文及格(60及以上)的人数
db.grade_1_4.aggregate([
{$match: {"score.chinese": {$gte: 60}}},
{$group: {_id: "$name", num: {$sum:1}}}
])
// 根据语文成绩的情况,分组,并统计人数
db.grade_1_4.aggregate([
{$group: {_id: "$score.chinese", num: {$sum:1}}}
])
// 按姓名分组,统计每个学生的兴趣爱好数量
db.grade_1_2.aggregate([
{$project: {name: "$name", len: {$size: "$hobby"}}}
])
db.grade_1_2.find({"name": "zhangsan7"},{length: {$size: "$hobby"}})
// 分桶
db.grade_1_4.aggregate([
{$bucket: {
groupBy: "$score.chinese",
boundaries: [0,60,80,90,100],
default: "impassible",
output: {count: {$sum: 1}}
}}
])
// $lookup
db.grade_1_4.aggregate([
{$lookup: {
from: "grade_1_1",
localField: "name",
foreignField: "name",
as: "nextDoor"
}}
])
// $exists
db.grade_1_2.find({sex: {$exists: false}})
// $cond
db.grade_1_4.aggregate([
{$project: {
name:1,
age:1,
_id: 0,
chinese: "$score.chinese",
evaluate: {
$cond: {if: {$gte: ["$score.chinese", 60]}, then: {
$cond: { if: {$gte: ["$score.chinese", 80]}, then: "优秀", else: "及格"}
}, else: "不及格"}
}
}}
])
七、下一次个练习
练习完这次后,我才发现MongoDB官方文档其实也带了很多demo,所以后面也去跟着敲了一遍
MongoDB官方文档版本-查询练习