MongoDB 入门指南(一):从 0 到 1 学会文档数据库
一、MongoDB 是什么?适合做什么?
如果你用过 MySQL,可能习惯了 “表 - 行 - 列
” 的结构。但 MongoDB 不一样,它是文档型数据库,用类似 JSON 的格式存数据,更灵活。
1. 为什么需要 MongoDB?
传统关系型数据库(如 MySQL)在面对 “三高” 需求时有点吃力:
- 高并发:大量用户同时读写
- 海量数据:存储 TB 甚至 PB 级数据;
- 高扩展:快速增加服务器应对增长。
MongoDB 专为这些场景设计,比如:
- 社交 App 存用户动态、朋友圈(数据格式多变);
- 游戏存用户装备、积分(读写频繁);
- 物联网存设备日志(数据量大,格式灵活)。
典型场景:用户评论、实时日志、物联网数据、社交动态
2. 核心概念(对比 MySQL)
MySQL | MongoDB | 说明 |
---|---|---|
数据库(Database) | 数据库(Database) | 作用相同,都是数据的容器 |
表(Table) | 集合(Collection) | 集合类似表,但不需要预先定义结构 |
行(Row) | 文档(Document) | 文档是存数据的基本单位,格式像 JSON |
列(Column) | 字段(Field) | 文档中的键值对,字段可以动态添加 |
例如,一条用户数据在 MongoDB 中是这样的(类似 JSON,称为 BSON):
{"_id": "1001", // 自动生成的唯一ID,类似主键"name": "小明","age": 20,"hobbies": ["打球", "听歌"] // 支持数组
}
3. BSON数据类型
类型 | 示例 | 说明 |
---|---|---|
String | “text” | UTF-8字符串 |
Int32 | NumberInt(25) | 32位整数 |
Double | 3.14 | 双精度浮点数 |
Boolean | true | 布尔值 |
Date | new Date() | 日期时间 |
Array | [1, “a”, true] | 数组 |
Object | {x:1} | 嵌套文档 |
二、安装 MongoDB(Windows 版)
1. 下载安装
官网下载:MongoDB Community Server
选择 Windows 版本,按提示安装(建议勾选 “Install MongoDB as a Service”,自动启动服务)。
2. 启动与连接
启动服务:安装后自动启动,默认端口 27017
。
连接数据库:
打开命令提示符(Win+R 输入cmd),输入mongo
(旧版本)或mongosh
(新版本),出现>提示符就成功了。
三、常用操作:数据库与集合
前言:以 “文章评论系统” 为实例
我们将以articledb
数据库中的comment
集合(存储文章评论)为例,讲解 MongoDB 的核心操作。先明确评论的数据结构,方便后续理解命令用途:
1. 数据库操作
命令 | 功能 | 示例 | 说明 |
---|---|---|---|
use db_name | 创建/切换数据库 | use articledb | 数据库不存在时自动创建 |
show dbs | 查看所有数据库 | show dbs | 显示非空数据库 |
db | 查看当前数据库 | db | 返回当前使用的数据库名 |
db.dropDatabase() | 删除当前数据库 | db.dropDatabase() | 谨慎操作!数据不可恢复 |
注意:
- 刚创建的数据库不会显示在show dbs中,需要插入数据后才会出现。
- 数据库名需满足:非空字符串、不含空格 /$/\ 等特殊字符、全小写、最多 64 字节。
- 保留数据库(无需手动创建):
- admin:权限根数据库,存全局管理员信息;
- local:本地数据,不参与复制(如单服务器日志);
- config:分片集群时存储配置信息。
2. 集合操作(类似表)
1. 集合的创建
(1)隐式创建(推荐)
无需手动创建,插入数据时自动生成集合:
# 向comment集合插入数据,若集合不存在则自动创建
db.comment.insertOne({...}) # 具体数据见后文
(2)显式创建(了解)
# 语法:db.createCollection(集合名)
db.createCollection("comment")
作用:提前创建集合(一般用于需要特殊配置的场景,如设置索引)。
2. 查看 / 删除集合
# 查看当前数据库的所有集合
show collections # 或 show tables# 删除集合(谨慎!)
db.comment.drop() # 返回true表示删除成功,false表示集合不存在
四、核心:文档的增删改查(CRUD)
以users集合为例,演示基本操作。
1. 插入文档(Create)
(1)插入单条文档
# 语法:db.集合名.insertOne(文档, {配置参数})
db.comment.insertOne({"articleid": "100000","content": "这篇文章很实用!","userid": "1001","nickname": "张三","createdatetime": new Date(), # 插入当前时间"likenum": NumberInt(15), # 整型点赞数(默认是double)"replynum": NumberInt(3),"state": "1","parentid": "0"},{writeConcern: 1, # 可选,数据写入确认级别(1表示至少写入1个节点)ordered: true # 可选,是否按顺序插入(单条插入时无意义)}
)
插入后会自动生成_id
字段(唯一标识,类似主键)。
参数说明:
- 第一个参数:要插入的文档(JSON 格式);
- writeConcern:保证数据写入的可靠性(新手默认 1 即可);
- ordered:批量插入时是否按顺序执行(单条插入可忽略)。
(2)批量插入文档
# 语法:db.集合名.insertMany([文档1, 文档2...], {配置参数})
db.comment.insertMany([{"articleid": "100000","content": "同意!我也学到了","userid": "1002","nickname": "李四","createdatetime": new Date(),"likenum": NumberInt(8),"replynum": NumberInt(0),"state": "1","parentid": "0"},{"articleid": "100001","content": "马克一下","userid": "1003","nickname": "王五","createdatetime": new Date(),"likenum": NumberInt(2),"replynum": NumberInt(1),"state": "1","parentid": "0"}],{ordered: true # 若为true,一条失败则后续都停止;false则继续插入其他文档}
)
2. 查询文档(Read)
# 基础语法:db.集合名.find(查询条件, 投影配置)
db.comment.find(query, projection)
参数说明:
- query:查询条件(JSON 格式,空对象{}表示查询所有);
- projection:控制返回的字段(1 = 显示,0 = 隐藏,默认显示所有字段)。
(1)基础查询
# 1. 查询所有评论
db.comment.find() # 等价于 db.comment.find({})# 2. 条件查询:查询文章100000的评论
db.comment.find({ "articleid": "100000" })# 3. 只返回第一条符合条件的记录
db.comment.findOne({ "userid": "1001" }) # 适合查单条数据(如详情)
###(2)投影查询(控制显示字段)
# 只显示content、nickname,隐藏_id(_id默认显示,需手动隐藏)
db.comment.find({ "articleid": "100000" }, # 查询条件{ "content": 1, "nickname": 1, "_id": 0 } # 投影配置
)
(3)复杂条件查询
场景 | 命令示例 | 说明 |
---|---|---|
模糊查询(含关键词) | db.comment.find({ “content”: /实用/ }) | 查内容包含 “实用” 的评论 |
范围查询(大于) | db.comment.find({ “likenum”: { $gt: NumberInt(10) } }) | 查点赞数 > 10 的评论($gt = 大于) |
范围查询(区间) | db.comment.find({ “likenum”: { $gte: 5, $lte: 20 } }) | 查点赞数 5~20 的评论(大于等于,lte = 小于等于) |
包含查询 | db.comment.find({ “userid”: { $in: [“1001”, “1002”] } }) | 查用户 1001 或 1002 的评论 |
多条件(且) | db.comment.find({ $and: [{ “articleid”: “100000” }, { “state”: “1” }] }) | 查文章 100000 的可见评论 |
多条件(或) | db.comment.find({ $or: [{ “likenum”: { $gt: 20 } }, { “replynum”: { $gt: 5 } }] }) | 查点赞 > 20 或回复 > 5 的评论 |
3. 更新文档(Update)
# 基础语法:db.集合名.updateOne(查询条件, 更新内容, {配置参数})
# 或批量更新:db.集合名.updateMany(...)
核心参数:
- upsert:若查询无匹配,是否插入新文档(默认 false);
- multi:是否批量更新(默认 false,只更第一条)。
(1)局部更新(推荐,用 $set)
# 只更新指定字段,不影响其他字段
db.comment.updateOne({ "_id": ObjectId("66b2f2a9f1b1e923c9d9x01") }, # 按主键定位{ $set: { "likenum": NumberInt(20), "state": "1" } } # $set确保局部更新
)
为什么用$set
:若直接写{ “likenum”: NumberInt(20)},会覆盖整个文档(只剩字段),set 可避免此问题。
(2)批量更新
# 更新所有userid=1003的评论昵称
db.comment.updateMany({ "userid": "1003" }, # 条件{ $set: { "nickname": "王五_新" } }, # 更新内容{ multi: true } # 批量更新(必须加,否则只更第一条)
)
(3)数值增减(用 $inc)
# 给某条评论的点赞数+1(适合用户点赞功能)
db.comment.updateOne({ "_id": ObjectId("66b2f2a9f1b1e923c9d9x01") },{ $inc: { "likenum": NumberInt(1) } } # $inc=自增(负数则自减)
)
4. 删除文档(Delete)
# 删除单条:db.集合名.deleteOne(条件)
db.comment.deleteOne({ "_id": ObjectId("66b2f2a9f1b1e923c9d9x01") })# 批量删除:db.集合名.deleteMany(条件)
db.comment.deleteMany({ "articleid": "100001" }) # 删除文章100001的所有评论# 清空集合(谨慎!)
db.comment.deleteMany({}) # 删除所有文档,保留集合结构
五、进阶查询:分页、排序与统计
1. 分页查询
# 语法:skip(跳过条数).limit(每页条数)
# 查第2页(每页2条):跳过前2条,取2条
db.comment.find().skip(2).limit(2)
顺序:先skip再limit,结合评论列表分页展示场景,避免一次性加载过多数据。
2. 排序
# 语法:sort({ 字段: 1 }) # 1=升序,-1=降序
# 按点赞数降序(热门评论在前),相同点赞数按时间升序
db.comment.find().sort({ "likenum": -1, "createdatetime": 1 })
执行顺序:先sort→再skip→最后limit(与命令编写顺序无关)。
3. 统计查询
# 统计总评论数
db.comment.countDocuments()# 条件统计:统计文章100000的可见评论数
db.comment.countDocuments({ "articleid": "100000", "state": "1" })
六、常用命令小结
操作 | 命令示例 | 说明 |
---|---|---|
切换数据库 | use articledb | 不存在则自动创建 |
插入单条评论 | db.comment.insertOne({…}) | 自动生成_id |
批量插入评论 | db.comment.insertMany([{…}, {…}]) | ordered 控制失败是否继续 |
查询所有评论 | db.comment.find() | 返回所有文档 |
条件查询 | db.comment.find({ “articleid”: “100000” }) | 按文章 ID 过滤 |
投影查询 | db.comment.find({}, { “content”: 1 }) | 只显示评论内容 |
局部更新 | db.comment.updateOne({…}, { $set: {…} }) | 避免覆盖文档 |
点赞数自增 | db.comment.updateOne({…}, { $inc: { “likenum”: 1 } }) | 适合用户互动场景 |
分页查询 | db.comment.find().skip(2).limit(2) | 第 2 页,每页 2 条 |
排序 | db.comment.find().sort({ “likenum”: -1 }) | 按点赞数降序 |
统计评论数 | db.comment.countDocuments({ “state”: “1” }) | 统计可见评论数 |
总结
MongoDB 的核心优势是灵活的文档结构和高效的读写性能,特别适合数据格式多变、并发量高的场景。
这篇讲了最基础的 CRUD 和操作命令,下一篇会介绍索引、聚合查询等进阶内容,跟着练几遍就能上手啦~