适合人群:读过上一篇,机器上装有 Docker(Desktop 或 Linux 引擎),准备把 MongoDB 真正跑起来的开发者。
本文基于 MongoDB 7.0 镜像与 Docker Compose v2 语法。所有命令在 Windows / macOS / Linux 的终端里均可用;Windows 下推荐 Git Bash 或 PowerShell。
一、为什么选择 Docker 而不是安装包
MongoDB 官方当然提供各平台的安装包,但对学习场景来说,Docker 有三个无法拒绝的理由:
- 版本切换零成本:
mongo:7.0换成mongo:8.0只是改一个标签; - 环境即代码:一个
docker-compose.yml提交进仓库,同事拉下来就是同一套数据库; - 为高可用实验铺路:第 09 篇的副本集要在单机上跑三个 MongoDB 进程,届时你会感谢今天练熟的 Compose 写法。
生产部署通常不用容器裸跑单实例,而是副本集或云托管服务;学习阶段的目标是用最低成本获得一个随时可丢弃、随时可重建的实例。
二、启动第一个实例
2.1 一条 docker run 跑通
先看最小可用版本,理解每个参数的职责:
1 | docker run -d --name mongo-dev \ |
| 参数 | 含义 | 不写的后果 |
|---|---|---|
-d |
后台运行 | 终端被日志占满 |
| `–name mongo-dev | 给容器起名,便于后续 docker exec |
只能用随机 ID 操作 |
-p 27017:27017 |
把容器的 27017 映射到宿主机 | 本机客户端连不上 |
-v mongo-data:/data/db |
数据写入具名卷 mongo-data |
删容器 = 数据全没 |
-e MONGO_INITDB_ROOT_* |
注入 root 账号密码 | 任何能连上端口的人都是管理员 |
验证它活着:
1 | docker ps # STATUS 应为 Up |
2.2 换成 Compose:系列标准姿势
实际开发更推荐把配置固化成文件。新建目录 mongodb-lab,写入 docker-compose.yml:
1 | services: |
1 | docker compose up -d # 启动 |
一个容易翻车的细节:
MONGO_INITDB_ROOT_*只在数据卷首次初始化时生效。如果你启动过一次之后再改密码环境变量,不会产生任何效果——要么down -v清卷重来,要么进 shell 用db.changeUserPassword()改。
三、mongosh:官方 Shell 入门
mongosh(MongoDB Shell)是与 MongoDB 交互的官方 JavaScript 环境,语法就是 JS:方法调用、变量、循环都成立。本系列的演示一律以它为准。
3.1 连接与 URI 结构
容器里已经内置了 mongosh,先从里面连:
1 | docker exec -it mongo-dev mongosh -u admin -p secret123 |
更常用的方式是在宿主机直接连(客户端工具单独安装,见 mongodb.com/try/download/shell):
1 | mongosh "mongodb://admin:secret123@localhost:27017" |
这条 URI 值得停下来拆解,后面每一篇都会和它打交道:
1 | mongodb://admin:secret123@localhost:27017/shop?authSource=admin |
两个初学者必问的问题顺带回答:认证用户建在哪个库里?root 账号属于 admin 库,所以 URI 上要带 authSource=admin(mongosh 交互登录时默认如此,写程序时容易漏);URI 结尾不带库名时连上的是默认测试上下文,不影响认证。
3.2 库、集合、文档三级实操
进入 shell 之后,上一篇文章的概念表就可以逐行验证了:
1 | show dbs // 列出所有数据库(至少有 admin、config、local) |
use shop 一个实际不存在的库,命令却不报错——因为 MongoDB 里库和集合都是惰性创建的:直到第一条数据落进来,它们才真正出现。亲手触发一次:
1 | db.products.insertOne({ name: "键盘 K870", price: NumberDecimal("299.00") }) |
顺便端详一下刚到手的这个 insertedId:上一篇说过 ObjectId 由”秒级时间戳 + 进程随机值 + 自增计数器”拼成,现在它是你环境里的实物了——把它交给任何支持解析的工具,都能直接读出创建时间。
对比 MySQL 的世界:你得先 CREATE DATABASE、再 CREATE TABLE、然后才能 INSERT;而这里是插入动作顺带完成了全部结构创建。库 → 集合 → 文档三级的全景如下:
自由是自由了,误拼写也不会有人拦你——use shpo 再插一条数据,你就多了个垃圾库。这正是上一篇说的”动态 Schema 的纪律问题”,第一课就从命名谨慎开始。
3.3 用 Compass 看见数据
命令行之外,装一个 Compass(官方免费 GUI)。连接方式与 mongosh 完全相同,把 URI 整串贴进去即可。
Compass 里最有价值的三个区域:
- 左侧数据库树:直观呈现”库 → 集合”两级结构;
- Documents 标签页:像看 JSON 文件一样浏览文档,还能看到每个字段的类型徽标(这比想象中重要——字段错位靠肉眼在这里最容易发现);
- Schema / Indexes 标签页:自动采样画出字段类型分布与已有索引,第 04、07 篇会回头用它做建模和调优的辅助工具。
本文不做 Compass 截图流水账,建议边读边点开自己刚插入的那条文档对照。
3.4 准备贯穿全系列的练习数据集
后续篇章的查询都基于一个小小的商品库,现在一次性灌进去(故意让四份文档结构不同,呼应上一篇的主题):
1 | use shop |
记住这个 shop.products 集合:第 03 篇的操作符、05 和 06 篇的聚合管道、07 篇的索引实验,都以它为样本。
四、顺手体验一组最小 CRUD
系统学习增删改查是下一篇的任务,这里只放一张”尝鲜清单”,让你确认环境完全可用——每一条都能直接在 mongosh 里跑:
1 | // 查:filter 条件写成嵌套 JSON |
注意观察返回值:MongoDB 的写操作结果自带 acknowledged 与计数信息,这是后续做幂等与对账的基础素材。操作符 $gt 这一套记法现在眼熟即可,第 03 篇会把整张操作符地图铺开。
五、常见坑清单
- 没挂数据卷就正式开测:容器一删数据蒸发。养成先写
-v的肌肉记忆; - 改了初始化账号以为生效:如前所述,root 账号只在卷首次初始化时创建,改动后务必
docker compose down -v重来或走changeUserPassword; - 27017 端口被占:宿主机若装过本地 MongoDB,
-p会绑定失败,docker logs里能看到 Address already in use; - URI 忘带
authSource:程序连接时报 “Authentication failed”,八成是拿普通库当认证库去验 root 账号; - shell 手滑拼错库名/集合名:没有报错、没有拦截,只有静默的新库新集合。定期
show dbs巡检,发现可疑库尽快db.dropDatabase(); - 金额写了浮点:
price: 79.9存成 Double 有精度尾巴,永远写NumberDecimal("79.90")。
六、总结与下一步
- Docker 是学习 MongoDB 的最低成本路径:一条
run或一小段 Compose 就能拥有可重建的实例; -v mongo-data:/data/db保住数据,MONGO_INITDB_ROOT_*只在首次初始化生效——这两点是新手事故 Top 2;- 连接 URI 的六段结构(协议 / 用户 / 密码 / 主机端口 / 目标库 /
authSource)值得背下来,之后 Spring Boot 配置还要用; - 库与集合惰性创建:第一个文档落地时结构才诞生,代价是拼写错误无人拦;
shop.products四条异构文档已就位,它是整个系列的教学数据集。
下一篇:《MongoDB 从零到一(03):CRUD 全解,find 操作符与更新表达式》——系统展开 find 的操作符体系、更新的六种姿势与 bulkWrite 批量写,把今天”尝鲜清单”里的每条命令讲透。详见 MongoDB 从零到一(03):CRUD 全解。
思考与练习
- 故意执行一次
use typo-db并插入一条数据,再用show dbs找到它并删除,体会”惰性创建”的两面性。- 把 Compose 里的映射改成
27018:27017,分别从 mongosh 与 Compass 用新端口连接成功。- 不查资料,口述一遍
mongodb://user:pass@host:27017/mydb?authSource=admin中mydb与authSource=admin各自的作用——这是新手报 Authentication failed 的头号原因。