目录
目标
- 了解MongoDB基本概念、特点、使用场景;
- 熟练使用命令行操作MongoDB,实现对数据的增删改查。
特点
MongoDB是使用c++开发的开源的NOSQL数据库。它有如下特点:
- 面向集合文档的存储:适合BSON(对JSON的扩展),一个BSON最大存储16M数据,如果超过了16M可以用引用,即在主表存副表的id值;
- 丰富的增删改查语言;
- 使用分片集群提升系统扩展;
- 支持数据持久化与复制;
- 内存映射存储引擎,把磁盘的IO操作转为对内存的操作。
MongoDB | 关系型数据库 |
---|---|
db(数据库) | database(数据库) |
collection(集合) | table(表) |
document(文档) | row(行) |
field(字段) | column(列) |
使用场景
- 没有复杂的关联操作;
- 对事务要求不高;
- 大数据量存储;
- 项目需求变更快,数据模型很难确定;
- 大量的评论、地理位置、文本查询等情况。
《操作数据库》
创建&切换数据库
/*创建一个名为school的数据库。*/
/*注意:如果没有school数据库则创建并切换,如果有,则直接切换到school库。*/
use school
查看数据库
/*查看我当前处于哪个数据库下。*/
db
/*查看所有数据库。注意:这里只查看拥有数据量的数据库。*/
show dbs
/*查看数据库信息。*/
db.stats()
删除数据库
/*先切换到要删除的数据库之下,然后执行删除操作。*/
db.dropDatabase()
《操作集合》
创建集合
/*创建一个名为student的集合。注意:当插入文档时,MongoDB会自动创建集合,所以不用创建单独集合也可以。*/
db.createCollection("student")
查看集合
/*查看所有集合。下面两个命令都可以。*/
show tables
show collections
删除集合
/*删除一个名为class的集合。注意:删除前先看看自己处于哪个数据库下。*/
db.class.drop()
《操作文档》
新增数据
创建一个文档
/*向student集合中增加一个文档。可以用insert或者insertOne。*/
db.student.insert({
"studentName": "张三"
});
db.student.insertOne({
"studentName": "李四"
});
/*向student集合中增加一个文档,如果存在相同的_id,则替换原来的数据。*/
db.student.save({
"_id": ObjectId("5fccd2023df4fc8f7b41d58f"),
"studentId": "000003",
"studentName": "百晓生"
});
创建多个文档
/*向student集合中增加多个文档。*/
db.student.insertMany([
{"name":"tom"},
{"name":"green"}
]);
/*为了接下来的测试,我多加点数据。*/
db.student.insertMany([{
"studentId": "000001",
"studentName": "孟星魂",
"grade": 100,
"level": "S",
"city": "常山",
"class": "123班",
"headmaster": "上官金虹",
"like": ["数学", "语文", "英语"],
"family": {
"mom": {"name": "邀月","phone": "77664895","age": 45,"address": "麦城"},
"dad": {"name": "燕南天","phone": "79987325","age": 47,"address": "华容道"}
},
"books": {
"martialArtsNovel": ["天龙八部", "鹿鼎记", "射雕英雄传"],
"fantasyNovels": ["凡人修仙传", "诛仙", "魔天记"]
},
"lastWeekIntegral":[1,6,3,8,2,4,8]
}, {
"studentId": "000002",
"studentName": "花满楼",
"grade": 100,
"level": "S",
"city": "许昌",
"class": "123班",
"headmaster": "上官金虹",
"like": ["数学", "语文", "英语","养花"],
"family": {
"mom": {"name": "怜星","phone": "79864895","age": 45,"address": "邯郸"},
"dad": {"name": "江小鱼","phone": "78887325","age": 47,"address": "建邺"}
},
"books": {
"martialArtsNovel": ["天龙八部", "小李飞刀"],
"fantasyNovels": ["凡人修仙传2", "诛仙"]
},
"lastWeekIntegral":[4,0,3,3,2,4,8]
}, {
"studentId": "000003",
"studentName": "百晓生",
"grade": 150,
"level": "SSS",
"city": "金陵",
"class": "124班",
"headmaster": "孙天机",
"like": ["语文", "数学", "智力"],
"family": {
"mom": {"name": "冷星","phone": "9987666","age": 45,"address": "长安"},
"dad": {"name": "万事通","phone": "7000005","age": 47,"address": "徐州"}
},
"books": {
"martialArtsNovel": ["楚留香", "小李飞刀"],
"fantasyNovels": ["风云3", "诛仙"]
},
"lastWeekIntegral":[4,-1,3,3,6,4,9]
}, {
"studentId": "000003",
"studentName": "陆小凤",
"grade": 120,
"level": "SS",
"city": "中原",
"class": "124班",
"headmaster": "孙天机",
"like": ["语文", "数学", "英语"],
"family": {
"mom": {"name": "柳烟","phone": "456895","age": 45,"address": "许昌"},
"dad": {"name": "郭白云","phone": "98867325","age": 47,"address": "常山"}
},
"books": {
"martialArtsNovel": ["小李飞刀", "天下第一"],
"fantasyNovels": ["魔天记", "诛仙"]
},
"lastWeekIntegral":[4,2,3,3,5,4,2]
}, {
"studentId": "000003",
"studentName": "扫地僧",
"grade": 200,
"level": "SSR",
"city": "中原",
"class": "少林",
"headmaster": "达摩",
"like": ["语文", "数学", "心经", "少林七十二绝技"],
"family": {
"dad": {"name": "慕容龙城","phone": "79864323435","age": 90,"address": "益州"},
"mom": {"name": "马冬梅","phone": "78887325","age": 47,"address": "沧州"}
},
"books": {
"martialArtsNovel": ["心经", "七种武器"],
"fantasyNovels": ["风云3", "诛仙"]
},
"lastWeekIntegral":[5,2,5,3,6,6,6]
}]);
查询数据
查询所有文档
/*查询student集合下的所有文档。*/
db.student.find()
/*查询student集合下的所有文档,并且格式化展示。*/
db.student.find().pretty()
返回指定字段
/*查询所有数据,返回studentName、city、_id字段。*/
db.student.find(
{},
{studentName:1,city:1}
).pretty()
/*查询所有数据,返回studentName、city字段。注意:只能都是1或者都是0,但_id是个例外。*/
db.student.find(
{},
{studentName:1,city:1,_id:0}
).pretty()
/*查询所有数据,不返回studentName、city字段。*/
db.student.find(
{},
{studentName:0,city:0}
).pretty()
/*查询studentName="扫地僧",返回dad和mom字段。*/
db.student.find(
{"studentName":"扫地僧"},
{"family":1}
).pretty()
比较查询运算符
/*=条件查询:studentName="扫地僧"的数据。例举两种方式。*/
db.student.find(
{"studentName":"扫地僧"}
).pretty()
db.student.find(
{"studentName":{$eq:"扫地僧"}}
).pretty()
/*<条件查询:grade<90的数据。*/
db.student.find(
{"grade":{$lt:90}}
).pretty()
/*<=条件查询:grade<=99的数据。*/
db.student.find(
{"grade":{$lte:99}}
).pretty()
/*>条件查询:grade>90的数据。*/
db.student.find(
{"grade":{$gt:90}}
).pretty()
/*>=条件查询:grade>=99的数据。*/
db.student.find(
{"grade":{$gte:99}}
).pretty()
/*≠条件查询:grade≠99的数据。*/
db.student.find(
{"grade":{$ne:99}}
).pretty()
/*或包含条件查询:查询like包含"语文"或包含"数学"的数据。*/
db.student.find(
{"like":{$in:["语文","数学"]}}
).pretty()
/*与包含条件查询:查询like包含"语文"且包含"数学"的数据。*/
db.student.find(
{"like":{$all:["语文","数学"]}}
).pretty()
/*非包含条件查询:查询studentName不为"扫地僧","陆小凤","百晓生","花满楼"的数据。*/
db.student.find(
{"studentName":
{$nin:["扫地僧","陆小凤","百晓生","花满楼"]}
}
).pretty()
/*模糊条件查询:查询studentName包含"晓"的数据。*/
db.student.find(
{"studentName":{"$regex":/晓/}}
).pretty()
db.student.find(
{"studentName":/晓/}
).pretty()
/*模糊条件查询:查询studentName以"陆"开头的数据。*/
db.student.find(
{"studentName":{"$regex":/^陆/}}
).pretty()
db.student.find(
{"studentName":/^李/}
).pretty()
/*模糊条件查询:查询studentName以"生"结尾的数据。*/
db.student.find(
{"studentName":{"$regex":/生$/}}
).pretty()
/*模糊条件查询:忽略大小写查询level="E"的数据。*/
db.student.find(
{"level":{"$regex":/e/i}}
).pretty()
db.student.find(
{"level":{"$regex":"e",'$options':'i'}}
).pretty()
逻辑查询运算符
/*与逻辑条件查询:查询city="常山"且level="S"的数据。*/
db.student.find(
{$and:[
{"city":"常山"},
{"level":"S"}
]}
).pretty();
/*或逻辑条件查询:查询city="常山"或studentId="000002"的数据。*/
db.student.find(
{$or:[
{"city":"常山"},
{"studentId":"000002"}
]}
).pretty();
/*非逻辑条件查询:查询studentName≠"孟星魂"的数据。*/
db.student.find(
{"studentName":{
$not:{"$eq":"孟星魂"}
}}
).pretty();
/*单条件或多条件取反查询:查询studentName≠"孟星魂"且city≠"许昌"的数据。*/
db.student.find(
{$nor:
[{studentName:"孟星魂"},{city:"许昌"}]
}
).pretty();
聚合查询
/*查询class有哪些。*/
db.student.aggregate(
{$group:{_id:"$class"}}
).pretty()
/*查询class=123班的总分grade。*/
db.student.aggregate(
{"$match":{"class":"123班"}},
{$group:{
_id:"$class",total:{$sum:"$grade"}
}}
).pretty()
/*查询class=123班的总分grade,不返回class。*/
db.student.aggregate(
{"$match":{"class":"123班"}},
{$group:{
_id:"$class",total:{$sum:"$grade"}
}},
{$project:{"_id":0}}
).pretty()
/*查询class=123班的总分grade,不反回class,只返回grade。*/
db.student.aggregate(
{"$match":{"class":"123班"}},
{$group:{
_id:"$class",total:{$sum:"$grade"}
}},
{$project:{"_id":0,"total":1}}
).pretty()
/*以class分组,查询各个班级的总分grade。*/
db.student.aggregate(
{$group:{
_id:"$class",total:{$sum:"$grade"}
}}
).pretty()
/*以class分组,查询各个班级的平均分。*/
db.student.aggregate(
{$group:{
_id:"$class",total:{$avg:"$grade"}
}}
).pretty()
/*以class分组,查询各个班级的最低grade。*/
db.student.aggregate(
{$group:{
_id:"$class",total:{$min:"$grade"}
}}
).pretty()
/*以class分组,查询各个班级的最高grade。*/
db.student.aggregate(
{$group:{
_id:"$class",total:{$max:"$grade"}
}}
).pretty()
/*以class分组,查询各个班级的最高grade,并对输出结果以grade降序排序。*/
db.student.aggregate(
{$group:{
_id:"$class",total:{$max:"$grade"}
}},
{$sort:{"total":-1}}
).pretty()
按分页查询
/*查询3条数据。*/
db.student.find().limit(3).pretty()
/*跳过6条数据。*/
db.student.find().skip(6).pretty()
/*从第2条开始查询,展示2条数据。注意:下标从0开始。*/
db.student.find().skip(1).limit(2).pretty()
按排序查询
/*按grade升序排序数据。*/
db.student.find().sort(
{"grade":1}
).pretty()
db.student.aggregate(
{$sort:{"grade":1}}
).pretty()
/*按grade降序排序数据。*/
db.student.find().sort(
{"grade":-1}
).pretty()
db.student.aggregate(
{$sort:{"grade":-1}}
).pretty()
/*按grade升序,level降序排序数据。*/
db.student.find().sort(
{"grade":1,"level":-1}
).pretty()
db.student.aggregate(
{$sort:{"grade":1,"level":-1}}
).pretty()
修改文档
/*修改:city="郑州",条件:studentName="孟星魂"。*/
db.student.update(
{studentName:"孟星魂"},
{$set:
{city:"郑州"}
}
)
/*修改:city="扬州",条件:city="许昌"。注意:这条sql只改变了一条符合条件的数据,因为multi默认为false,表示只更新一条符合条件的数据。*/
db.student.update(
{city:"许昌"},
{$set:
{city:"扬州"}
}
)
/*修改:city="扬州",条件:city="岳阳"。注意:这条sql改变了所有符合条件的数据。*/
db.student.update(
{city:"许昌"},
{$set:
{city:"扬州"}
},
{multi:true}
)
db.student.updateMany(
{city:"许昌"},
{$set:
{city:"扬州"}
}
)
/*修改:city="北京",如果没有该数据,则向集合中插入{city:"北京"}文档。条件:city="东京"。*/
db.student.update(
{city:"东京"},
{$set:
{city:"北京"}
}
)
/*修改:level="S",条件:grade>=90的所有数据。*/
db.student.update(
{"grade":{$gte:90}},
{$set:
{"level":"S"}
},
{multi:true}
)
/*修改:level="A",条件:grade>=89且grade<=80的所有数据。这里写了两种方法。*/
db.student.update(
{"grade":
{"$gte":80,"$lte":89}
},
{$set:
{"level":"A"}
},
{multi:true}
)
db.student.update(
{"$and":[
{"grade":{"$gte":80}},
{"grade":{"$lte":89}}
]},
{$set:
{"level":"B"}
},
{multi:true}
)
/*修改:去掉city字段,条件:studentName="孟星魂"。*/
db.student.updateMany(
{"studentName":"孟星魂"},
{$unset:
{"city":""}
}
)
/*修改:修改studentName字段名为name,条件:studentName="孟星魂"。*/
db.student.updateMany(
{studentName:"孟星魂"},
{$rename:
{"studentName":"name"}
}
);
/*修改:向like中追加"兵器"、"武力排名",条件:studentName=百晓生。*/
db.student.updateMany(
{studentName:"百晓生"},
{"$addToSet":{
"like":{"$each":["兵器","武力排名"]}
}
}
)
/*修改:删除like中的"语文"、"数学"、"英语",条件:studentName=百晓生。*/
db.student.updateMany(
{studentName:"百晓生"},
{"$pullAll":{
"like":["语文","数学","英语"]
}
}
)
db.student.updateMany(
{studentName:"百晓生"},
{"$pull":{
"like":{$in:["语文","数学","英语"]}
}
}
)
删除文档
/*删除city="北京"的数据。这里删除了所有符合条件的数据,因为justOne=false。*/
db.student.remove(
{"city":"北京"}
);
/*删除city="扬州"的数据。这里只删除了一条符合条件的数据,因为justOne=true。*/
db.student.remove(
{"city":"扬州"},
{justOne:true}
);
数组的常见操作
元素包含关系
/*或包含条件查询:查询like包含"语文"、"数学"任意一个科目的数据。*/
db.student.find(
{"like":{$in:["语文","数学"]}}
).pretty()
/*与包含条件查询:查询like包含"语文"、"数学"两个科目的数据。*/
db.student.find(
{"like":{$all:["语文","数学"]}}
).pretty()
/*非包含条件查询:查询studentName不为"扫地僧","陆小凤","百晓生","花满楼"的数据。*/
db.student.find(
{"studentName":
{$nin:["扫地僧","陆小凤","百晓生","花满楼"]}
}
).pretty()
/*查询like字段等于:"数学"、"语文"、"英语"三个科目的数据。这里严格要求数组大小是3且元素有序。*/
db.student.find(
{like:["数学","语文","英语"]}
).pretty();
/*查询like字段前三条分别是:"数学"、"语文"、"英语"的数据。*/
db.student.find(
{"like.0":"数学","like.1":"语文","like.2":"英语"}
).pretty();
/*查询like字段第2条和第3条数据*/
db.student.find(
{},
{"like":{$slice:[1,2]},studentName:1}
).pretty();
数组大小
/*查询like字段元素个数等于4个的数据。*/
db.student.find(
{like:{"$size":4}}
).pretty();
/*查询所有数据like字段元素的个数,且只展示元素个数与studentName。*/
db.student.aggregate(
{$project:
{count:{$size: "$like"},
"studentName":1
}
}
).pretty();
db.student.find(
{},
{"studentName":1,count:{$size: "$like"}}
).pretty();
/*以class分组,统计like字段元素的总和。*/
db.student.aggregate(
{"$group":
{_id:"$class",total:{"$sum":{$size:"$like"}}}
}
).pretty();
元素排序
/*查询所有数据,将lastWeekIntegral的元素以升序展示出来。*/
db.student.aggregate(
{$sort:{lastWeekIntegral:1}}
).pretty()
新增减少数组元素
/*给studentName="百晓生"的like字段新增"武功"、"江湖"元素。*/
db.student.updateMany(
{studentName:"百晓生"},
{"$addToSet":
{ "like" : { "$each" : [ "武功" , "江湖"]}}
}
)