下面是去除个人信息、示例姓名、具体城市和全部图片内容后的第二篇版本。
MongoDB Beginner Guide 02:MongoDB Shell 常用命令与 CRUD 数据操作
前言
上一篇主要介绍了 MongoDB 的基本概念,包括 NoSQL、文档模型、Database、Collection、Document,以及 MongoDB Server、MongoDB Shell 和 MongoDB Compass 之间的关系。
理解这些概念之后,下一步就是实际操作数据库。
数据库中最常见的基础操作可以概括为 CRUD:
| 缩写 | 英文 | 含义 |
|---|---|---|
| C | Create | 创建或插入数据 |
| R | Read | 读取或查询数据 |
| U | Update | 更新数据 |
| D | Delete | 删除数据 |
本文主要使用 MongoDB Shell,也就是mongosh,完成数据库、集合和文档的基本操作,同时简单介绍 MongoDB Compass 中对应的可视化操作。
1. 进入 MongoDB Shell
在开始操作之前,需要确保 MongoDB Server 已经启动。
打开终端,输入:
mongosh如果连接成功,通常会看到类似以下内容:
Connecting to: mongodb://127.0.0.1:27017/ test>其中:
test>表示当前连接到了名为test的数据库。
MongoDB 本地服务的默认连接地址通常是:
mongodb://localhost:27017或者:
mongodb://127.0.0.1:27017如果执行mongosh后出现连接失败,应先检查 MongoDB Server 是否已经启动,以及默认的27017端口是否正常监听。
2. Database 基础操作
2.1 查看所有数据库
在mongosh中输入:
show databases也可以使用:
show dbs系统会列出当前 MongoDB 实例中已经存在的数据库,例如:
admin config local这些数据库通常由 MongoDB 系统自动创建。
2.2 查看当前数据库
输入:
db可能输出:
test这表示当前正在操作test数据库。
2.3 切换数据库
使用use命令切换数据库:
use demo_database执行后会显示:
switched to db demo_database再次输入:
db可以确认当前数据库已经切换为:
demo_database需要注意的是,执行use demo_database并不一定会立即创建数据库。
MongoDB 通常会在数据库中第一次写入数据后,才正式创建并显示该数据库。
因此,刚执行完use demo_database后,如果运行:
show databases可能暂时看不到它。
3. Collection 基础操作
Collection 可以理解为关系型数据库中的 Table,也就是数据表。
例如,可以在demo_database数据库中创建一个名为users的 Collection,用于保存用户信息。
3.1 查看当前数据库中的 Collection
输入:
show collections如果当前数据库中还没有 Collection,可能不会显示任何结果。
3.2 手动创建 Collection
可以使用:
db.createCollection("users")执行成功后会返回:
{ ok: 1 }再次运行:
show collections可以看到:
users不过,在大多数基础项目中,不需要提前创建 Collection。
当我们向一个不存在的 Collection 中插入数据时,MongoDB 可以自动创建它。
4. Create:插入数据
4.1 插入一条数据
首先切换到目标数据库:
use demo_database然后向usersCollection 插入一条数据:
db.users.insertOne({ username: "user_001", age: 20, status: "active", skills: ["Python", "MongoDB"] })执行成功后,会返回类似结果:
{ acknowledged: true, insertedId: ObjectId("...") }其中:
acknowledged: true表示数据库已经确认写入操作;insertedId表示新文档的唯一标识;如果没有手动设置
_id,MongoDB 会自动生成一个_id字段。
插入后的文档结构类似:
{ _id: ObjectId("..."), username: "user_001", age: 20, status: "active", skills: [ "Python", "MongoDB" ] }4.2 插入多条数据
使用insertMany()可以一次插入多个文档:
db.users.insertMany([ { username: "user_002", age: 21, status: "active" }, { username: "user_003", age: 22, status: "inactive" }, { username: "user_004", age: 19, status: "active" } ])执行成功后,会返回多个文档的_id:
{ acknowledged: true, insertedIds: { '0': ObjectId("..."), '1': ObjectId("..."), '2': ObjectId("...") } }insertOne()适合插入一条文档,insertMany()适合一次插入多条文档。
5. Read:查询数据
MongoDB 主要使用find()和findOne()查询 Collection 中的文档。
5.1 查询所有文档
db.users.find()该命令会返回usersCollection 中的全部文档。
5.2 根据字段查询
查询用户名为user_001的文档:
db.users.find({ username: "user_001" })查询年龄为 20 的文档:
db.users.find({ age: 20 })查询状态为active的文档:
db.users.find({ status: "active" })MongoDB 查询条件通常使用一个文档表示:
{ field: value }其中:
field是字段名称;value是需要匹配的字段值。
5.3 查询一条文档
使用findOne()返回满足条件的一条文档:
db.users.findOne({ username: "user_001" })find()返回多个匹配结果,findOne()只返回其中一条。
5.4 使用比较运算符
查询年龄大于 20 的文档:
db.users.find({ age: { $gt: 20 } })查询年龄大于或等于 20 的文档:
db.users.find({ age: { $gte: 20 } })查询年龄小于 22 的文档:
db.users.find({ age: { $lt: 22 } })查询年龄在 20 到 22 之间的文档:
db.users.find({ age: { $gte: 20, $lte: 22 } })常见比较运算符如下:
| 运算符 | 含义 |
$eq | 等于 |
$ne | 不等于 |
$gt | 大于 |
$gte | 大于或等于 |
$lt | 小于 |
$lte | 小于或等于 |
$in | 匹配列表中的任意值 |
$nin | 不匹配列表中的值 |
5.5 使用多个查询条件
查询状态为active,并且年龄大于 20 的文档:
db.users.find({ status: "active", age: { $gt: 20 } })同一个查询文档中的多个字段,默认表示 AND 条件。
也可以明确使用$and:
db.users.find({ $and: [ { status: "active" }, { age: { $gt: 20 } } ] })查询状态为active或inactive的文档:
db.users.find({ $or: [ { status: "active" }, { status: "inactive" } ] })在这个例子中,也可以使用$in简化:
db.users.find({ status: { $in: ["active", "inactive"] } })5.6 控制返回字段
有时候不需要返回完整文档,只需要查看其中一部分字段。
例如,只返回用户名和年龄:
db.users.find( {}, { username: 1, age: 1 } )MongoDB 默认会返回_id字段。
如果不需要显示_id,可以写成:
db.users.find( {}, { _id: 0, username: 1, age: 1 } )其中:
1表示返回该字段;0表示不返回该字段。
5.7 排序
按照年龄升序排列:
db.users.find().sort({ age: 1 })按照年龄降序排列:
db.users.find().sort({ age: -1 })其中:
1表示升序;-1表示降序。
5.8 限制返回数量
只返回前两条数据:
db.users.find().limit(2)排序和限制可以组合使用:
db.users .find() .sort({ age: -1 }) .limit(2)这段命令表示:
按照年龄从大到小排序,并返回前两条文档。
5.9 统计文档数量
统计 Collection 中全部文档的数量:
db.users.countDocuments()统计状态为active的文档数量:
db.users.countDocuments({ status: "active" })6. Update:更新数据
6.1 更新一条文档
将user_001的年龄修改为 21:
db.users.updateOne( { username: "user_001" }, { $set: { age: 21 } } )第一部分是筛选条件:
{ username: "user_001" }第二部分是更新内容:
{ $set: { age: 21 } }执行成功后可能返回:
{ acknowledged: true, matchedCount: 1, modifiedCount: 1, upsertedCount: 0 }其中:
matchedCount:匹配到的文档数量;modifiedCount:实际被修改的文档数量;upsertedCount:通过 upsert 新插入的文档数量。
6.2 添加新字段
使用$set不仅可以修改字段,还可以添加字段:
db.users.updateOne( { username: "user_001" }, { $set: { level: "beginner" } } )更新后,文档会增加:
{ level: "beginner" }6.3 更新多条文档
为所有状态为active的用户添加一个字段:
db.users.updateMany( { status: "active" }, { $set: { verified: true } } )updateOne()只更新一条匹配文档,updateMany()会更新所有满足条件的文档。
6.4 数值字段增加
将指定用户的年龄增加 1:
db.users.updateOne( { username: "user_001" }, { $inc: { age: 1 } } )$inc常用于:
阅读量增加;
点赞数增加;
访问次数统计;
库存数量变化;
计数器更新。
6.5 删除字段
使用$unset删除字段:
db.users.updateOne( { username: "user_001" }, { $unset: { level: "" } } )执行后,level字段会从文档中删除。
6.6 向数组添加元素
向skills数组中添加一个元素:
db.users.updateOne( { username: "user_001" }, { $push: { skills: "Pandas" } } )更新后:
{ skills: [ "Python", "MongoDB", "Pandas" ] }$push会直接向数组中添加元素。
如果希望避免添加重复值,可以使用$addToSet:
db.users.updateOne( { username: "user_001" }, { $addToSet: { skills: "Pandas" } } )6.7 从数组中删除元素
使用$pull删除数组中的指定值:
db.users.updateOne( { username: "user_001" }, { $pull: { skills: "Pandas" } } )7. Delete:删除数据
7.1 删除一条文档
删除用户名为user_004的文档:
db.users.deleteOne({ username: "user_004" })执行后可能返回:
{ acknowledged: true, deletedCount: 1 }其中,deletedCount表示实际删除的文档数量。
7.2 删除多条文档
删除所有年龄小于 20 的文档:
db.users.deleteMany({ age: { $lt: 20 } })deleteOne()删除一条匹配文档,deleteMany()删除所有匹配文档。
7.3 删除 Collection 中的全部文档
db.users.deleteMany({})空查询条件{}表示匹配全部文档。
因此,这条命令会清空usersCollection 中的全部数据。
需要注意:
deleteMany({})不会删除 Collection 本身,只会删除其中的文档。
执行这类命令前,应再次确认当前 Database 和 Collection 是否正确。
7.4 删除 Collection
删除整个usersCollection:
db.users.drop()deleteMany({})与drop()的区别:
| 命令 | 结果 |
deleteMany({}) | 删除全部文档,保留 Collection |
drop() | 删除整个 Collection |
8. MongoDB Compass 基础操作
MongoDB Compass 是 MongoDB 官方提供的图形化数据库管理工具。
相比命令行,Compass 更适合观察 MongoDB 的数据结构。
主要功能包括:
查看 Database;
查看 Collection;
浏览 Document;
插入数据;
设置查询条件;
修改数据;
删除数据;
查看索引。
8.1 连接本地 MongoDB
打开 MongoDB Compass,在连接地址中输入:
mongodb://localhost:27017点击连接后,可以查看本地 MongoDB 中已经存在的数据库。
8.2 创建 Database 和 Collection
在 Compass 中选择创建数据库,并填写:
Database Name:demo_database Collection Name:users创建完成后,可以看到以下结构:
demo_database └── users8.3 插入 Document
进入:
demo_database → users → Documents选择插入数据,并输入:
{ "username": "user_001", "age": 20, "status": "active", "skills": [ "Python", "MongoDB" ] }插入后,可以直接在 Documents 页面中查看对应文档。
8.4 使用 Filter 查询数据
查询状态为active的文档:
{ status: "active" }查询年龄大于 20 的文档:
{ age: { $gt: 20 } }查询多个状态:
{ status: { $in: ["active", "inactive"] } }Compass 中的 Filter 与mongosh中find()的查询条件基本一致。
例如,以下两种方式表示相同的查询逻辑:
Compass Filter:
{ status: "active" }MongoDB Shell:
db.users.find({ status: "active" })8.5 修改 Document
在 Documents 页面找到目标文档后,可以直接编辑字段。
例如,将:
age: 20修改为:
age: 21保存后,MongoDB 会更新对应文档。
8.6 删除 Document
在 Documents 页面选择目标文档后,可以执行删除操作。
删除前需要确认当前选择的文档是否正确,因为删除后的数据通常无法直接恢复。
9. MongoDB Shell 与 Compass 如何选择?
| 场景 | 推荐工具 |
| 第一次学习 MongoDB | Compass |
| 观察文档结构 | Compass |
| 快速编辑单条文档 | Compass |
| 学习 MongoDB 查询语法 | mongosh |
| 批量执行数据操作 | mongosh |
| 测试复杂查询条件 | mongosh |
| 检查命令执行结果 | Compass |
| 编写自动化流程 | Python Driver 或其他语言驱动 |
Compass 和mongosh并不是互相替代的关系。
比较合适的学习方式是:
在 Compass 中观察数据结构 ↓ 在 mongosh 中练习 CRUD 命令 ↓ 回到 Compass 检查数据变化10. CRUD 命令速查表
| 需求 | 命令 |
| 查看数据库 | show databases |
| 切换数据库 | use demo_database |
| 查看当前数据库 | db |
| 查看 Collection | show collections |
| 创建 Collection | db.createCollection("users") |
| 插入一条文档 | db.users.insertOne({...}) |
| 插入多条文档 | db.users.insertMany([...]) |
| 查询全部文档 | db.users.find() |
| 查询一条文档 | db.users.findOne({...}) |
| 统计文档数量 | db.users.countDocuments() |
| 更新一条文档 | db.users.updateOne({...}, {...}) |
| 更新多条文档 | db.users.updateMany({...}, {...}) |
| 删除一条文档 | db.users.deleteOne({...}) |
| 删除多条文档 | db.users.deleteMany({...}) |
| 清空 Collection | db.users.deleteMany({}) |
| 删除 Collection | db.users.drop() |
11. 常见问题
11.1 执行 use 后看不到数据库
执行:
use demo_database然后运行:
show databases却看不到demo_database。
这是因为数据库中还没有真正写入数据。
可以插入一条文档:
db.users.insertOne({ username: "user_001" })再次执行:
show databases通常就可以看到该数据库。
11.2 找不到刚插入的数据
首先检查当前数据库:
db然后检查 Collection:
show collections最后执行:
db.users.find()很多时候,数据被插入到了另一个 Database 或 Collection。
11.3 updateOne 没有修改数据
检查返回结果中的:
matchedCount modifiedCount如果结果为:
matchedCount: 0说明没有文档满足查询条件。
如果结果为:
matchedCount: 1 modifiedCount: 0说明已经找到文档,但更新后的值与原来的值相同。
11.4 deleteOne 没有删除数据
需要检查字段名称、字段值和数据类型是否一致。
例如,数据库中的字段是数字:
{ age: 20 }但查询时使用了字符串:
{ age: "20" }数字20和字符串"20"是不同的数据类型,因此不会匹配。
11.5 删除操作没有报错,但数据还存在
检查返回结果中的:
deletedCount如果:
deletedCount: 0说明没有文档满足删除条件。
删除命令执行成功,并不代表一定删除了文档。
总结
本文主要整理了 MongoDB Shell 和 Compass 中最基础的数据库操作,包括:
Database 与 Collection 管理;
使用
insertOne()和insertMany()插入数据;使用
find()和查询运算符筛选数据;使用
updateOne()和updateMany()修改数据;使用
deleteOne()和deleteMany()删除数据;在 MongoDB Compass 中完成对应的可视化操作。
MongoDB CRUD 命令本身并不复杂,真正需要明确的是三层结构:
Database ↓ Collection ↓ Document每次执行命令之前,都应该确认:
当前使用的是哪个 Database;
当前操作的是哪个 Collection;
查询条件会匹配哪些 Document;
更新或删除操作会影响多少条数据。
在掌握 MongoDB Shell 和 CRUD 基础操作后,下一步可以继续学习如何使用 PyMongo 将 Python 程序与 MongoDB 连接起来,实现数据的自动写入、查询和处理。