一、实验概述
本实验聚焦MongoDB命令行操作,涵盖数据库管理、集合操作、文档的增删改查以及索引创建等核心内容。通过实际操作,深入理解MongoDB"文档型存储"的灵活性,提升非关系型数据库的操作能力。
二、数据库操作
2.1 查看数据库
使用show dbs命令查看当前所有数据库:
>show dbs admin0.000GB// 权限数据库local0.000GB// 本地数据库(不复制)test0.000GB// 默认测试数据库注意:没有插入数据的自定义数据库不会显示在列表中。
2.2 创建/切换数据库
使用use命令创建或切换数据库:
>use myDB switched to db myDB如果数据库不存在,MongoDB会在第一次插入数据时自动创建。
2.3 统计数据库信息
使用stats()方法查看数据库统计信息:
>use myDB>db.stats(){"db":"myDB","collections":2,"views":0,"objects":5,"avgObjSize":59.2,"dataSize":296,"storageSize":32768,"numExtents":0,"indexes":2,"indexSize":32768,"scaleFactor":1,"fsUsedSize":0,"fsTotalSize":0,"ok":1}2.4 删除数据库
>db.dropDatabase(){"dropped":"myDB","ok":1}三、集合操作
3.1 查看集合
>use test>db.getCollectionNames()["students","orders"]>show collections students orders3.2 显式创建集合
使用createCollection()方法显式创建集合:
>db.createCollection("students"){"ok":1}带参数的创建(固定大小集合):
>db.createCollection("log",{capped:true,size:1024,max:100})| 参数 | 类型 | 说明 |
|---|---|---|
capped | Boolean | 启用固定大小集合,达到上限自动覆盖最旧条目 |
size | Number | 上限集合的最大大小(字节) |
max | Number | 上限集合中允许的最大文档数 |
3.3 隐式创建集合
当插入文档时,如果集合不存在,MongoDB会自动创建:
>db.students.insert({name:"张三",age:20})WriteResult({"nInserted":1})>show collections students3.4 其他集合操作
// 重命名集合>db.myDB.renameCollection("orders2014"){"ok":1}// 删除集合>db.orders2014.drop()true四、文档操作
4.1 插入文档
单条插入
>db.students.insert({name:"张三",age:20,major:"计算机科学"})WriteResult({"nInserted":1})批量插入
>db.students.insertMany([{name:"李四",age:21,major:"软件工程"},{name:"王五",age:19,major:"数据科学"},{name:"赵六",age:22,major:"人工智能"}]){"acknowledged":true,"insertedIds":[ObjectId("5ba7342c7f9318ea62161352"),ObjectId("5ba7342c7f9318ea62161353"),ObjectId("5ba7342c7f9318ea62161354")]}指定 _id 插入
>db.students.insert({_id:1001,name:"孙七",age:23})WriteResult({"nInserted":1})变量方式插入
>vardoc={name:"周八",age:24,score:85}>db.students.insert(doc)WriteResult({"nInserted":1})4.2 有序与无序插入
ordered: true(默认)
遇到_id重复时停止后续插入:
>db.students.insertMany([{_id:1,name:"A"},{_id:1,name:"B"},// 重复,报错{_id:3,name:"C"}// 不再插入],{ordered:true})// 结果:仅插入第一条,后续终止ordered: false
跳过错误文档,继续插入其他文档:
>db.students.insertMany([{_id:1,name:"A"},{_id:1,name:"B"},// 重复,跳过{_id:3,name:"C"}// 继续插入],{ordered:false})// 结果:插入第1条和第3条4.3 更新文档
update() 方法
// 更新单条文档(默认只更新第一条匹配)>db.students.update({name:"张三"},{$set:{age:21}})WriteResult({"nMatched":1,"nUpserted":0,"nModified":1})// 更新多条文档>db.students.update({major:"计算机科学"},{$set:{score:90}},{multi:true})// 不存在则插入(upsert)>db.students.update({name:"钱九"},{$set:{age:25,major:"网络安全"}},{upsert:true})save() 方法
// 若 _id 存在则更新,不存在则插入>db.students.save({_id:1001,name:"孙七",age:24,major:"大数据"})WriteResult({"nMatched":1,"nUpserted":0,"nModified":1})4.4 删除文档
// 删除所有文档>db.students.deleteMany({}){"acknowledged":true,"deletedCount":5}// 删除符合条件的所有文档>db.students.deleteMany({status:"A"}){"acknowledged":true,"deletedCount":2}// 删除符合条件的一条文档>db.students.deleteOne({status:"D"}){"acknowledged":true,"deletedCount":1}注意:
remove()方法已不推荐使用,官方建议使用deleteOne()和deleteMany()。
五、查询操作
5.1 基本查询
// 查询所有文档>db.students.find()// 格式化输出>db.students.find().pretty()// 条件查询>db.students.find({age:20})// 多条件查询(AND)>db.students.find({name:"张三",age:20})5.2 条件操作符
| 操作 | 语法 | 示例 | 等价SQL |
|---|---|---|---|
| 等于 | {key:value} | db.test.find({price:24}) | WHERE price=24 |
| 大于 | {key:{$gt:value}} | db.test.find({price:{$gt:24}}) | WHERE price>24 |
| 小于 | {key:{$lt:value}} | db.test.find({price:{$lt:24}}) | WHERE price<24 |
| 大于等于 | {key:{$gte:value}} | db.test.find({price:{$gte:24}}) | WHERE price>=24 |
| 小于等于 | {key:{$lte:value}} | db.test.find({price:{$lte:24}}) | WHERE price<=24 |
| 不等于 | {key:{$ne:value}} | db.test.find({price:{$ne:24}}) | WHERE price!=24 |
| OR | {$or:[...]} | db.test.find({$or:[{name:"A"},{price:24}]}) | WHERE name="A" OR price=24 |
5.3 特定类型查询
// 查询 age 为 null 的文档>db.test.find({age:null})// 查询数组包含特定元素>db.test.find({tags:"MongoDB"})5.4 游标操作
// 获取游标>varcursor=db.students.find()// 遍历游标>while(cursor.hasNext()){...printjson(cursor.next())...}// 常用游标方法>db.students.find().count()// 统计数量>db.students.find().limit(5)// 限制返回5条>db.students.find().skip(10)// 跳过前10条>db.students.find().sort({age:-1})// 按age降序排序>db.students.find().toArray()// 转为数组游标生命周期:
- 创建:执行
find()时在服务器端创建 - 销毁条件:
- 客户端游标变量超出作用域
- 游标遍历完成或客户端主动终止
- 服务器端10分钟内未操作
六、索引操作
6.1 创建单键索引
>db.students.createIndex({score:1}){"createdCollectionAutomatically":false,"numIndexesBefore":1,"numIndexesAfter":2,"ok":1}
1表示升序,-1表示降序。
6.2 查看索引
// 查看集合索引>db.students.getIndexes()// 查看数据库所有索引>db.getCollectionNames().forEach(function(collection){...print("Indexes for "+collection+":");...printjson(db[collection].getIndexes());...})6.3 查询性能分析
使用索引字段查询
>db.students.find({score:{$gt:80}}).explain("executionStats")输出关键信息:
"stage" : "IXSCAN"—— 索引扫描"indexName" : "score_1"—— 使用了score索引"totalDocsExamined"—— 检查的文档数(较少)
不使用索引字段查询
>db.students.find({name:"张三"}).explain("executionStats")输出关键信息:
"stage" : "COLLSCAN"—— 全集合扫描"totalDocsExamined"—— 检查的文档数(较多)
6.4 删除索引
// 删除指定索引>db.students.dropIndex("score_1")// 删除所有索引(保留 _id 索引)>db.students.dropIndexes()七、附录:常用命令速查表
| 操作类别 | 命令 | 说明 |
|---|---|---|
| 数据库 | use dbname | 切换/创建数据库 |
| 数据库 | show dbs | 查看所有数据库 |
| 数据库 | db.stats() | 查看数据库统计 |
| 数据库 | db.dropDatabase() | 删除当前数据库 |
| 集合 | db.createCollection(name) | 显式创建集合 |
| 集合 | show collections | 查看所有集合 |
| 集合 | db.collection.drop() | 删除集合 |
| 文档 | db.col.insert(doc) | 插入文档 |
| 文档 | db.col.insertMany(docs) | 批量插入 |
| 文档 | db.col.update(query,update) | 更新文档 |
| 文档 | db.col.deleteOne(query) | 删除单条 |
| 文档 | db.col.deleteMany(query) | 删除多条 |
| 查询 | db.col.find(query) | 查询文档 |
| 查询 | db.col.find().pretty() | 格式化输出 |
| 索引 | db.col.createIndex({key:1}) | 创建索引 |
| 索引 | db.col.getIndexes() | 查看索引 |
| 索引 | db.col.dropIndex(name) | 删除索引 |
| 索引 | db.col.explain() | 查询执行计划 |