docker 命令创建mongoDB
docker pull mongo
docker run -d --name my-mongo \-e MONGO_INITDB_ROOT_USERNAME=root \-e MONGO_INITDB_ROOT_PASSWORD=123456 \-v /my/data/mongo:/data/db \-p 27017:27017 \mongodocker run -d --name my-mongo -e MONGO_INITDB_ROOT_USERNAME=root -e MONGO_INITDB_ROOT_PASSWORD=123456 -p 27017:27017 mongodocker exec -it my-mongo mongosh -u root -p 123456
docker-compose创建mongoDB
目录结构
建议这样放:
project/
│── docker-compose.yml │
── init-mongo.js │
── mongo-data/ (数据会存这里)
init-mongo.js
(初始化脚本)
db = db.getSiblingDB('myapp'); // 切换/创建数据库 myapp// ========== users 集合 ==========
db.createCollection('users');// 插入用户数据
db.users.insertMany([{ username: "alice", email: "alice@example.com", role: "admin" },{ username: "bob", email: "bob@example.com", role: "user" }
]);// 索引:用户名唯一
db.users.createIndex({ username: 1 }, { unique: true });// 索引:邮箱唯一
db.users.createIndex({ email: 1 }, { unique: true });// 索引:角色 + 用户名 组合索引(方便按角色查用户并排序)
db.users.createIndex({ role: 1, username: 1 });// ========== accounts 集合 ==========
db.createCollection('accounts');// 插入账户数据
db.accounts.insertOne({ user: "alice", balance: 1000 });// 索引:user 字段(常用外键查询)
db.accounts.createIndex({ user: 1 });// 索引:余额 balance 降序(方便做排行榜)
db.accounts.createIndex({ balance: -1 });
修改后的 docker-compose.yml
version: '3.8'services:mongodb:image: mongo:6.0container_name: my-mongorestart: alwaysenvironment:MONGO_INITDB_ROOT_USERNAME: rootMONGO_INITDB_ROOT_PASSWORD: 123456ports:- "27017:27017"volumes:- ./mongo-data:/data/db- ./init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:romongo-express:image: mongo-express:latestcontainer_name: my-mongo-expressrestart: alwaysports:- "8081:8081"environment:ME_CONFIG_MONGODB_ADMINUSERNAME: rootME_CONFIG_MONGODB_ADMINPASSWORD: 123456ME_CONFIG_MONGODB_SERVER: mongodbdepends_on:- mongodb
添加下面的配置可以设置express的用户名和密码,包括可以访问的host
environment:ME_CONFIG_MONGODB_ADMINUSERNAME: rootME_CONFIG_MONGODB_ADMINPASSWORD: 123456ME_CONFIG_MONGODB_SERVER: mongodb# 添加以下配置解决警告ME_CONFIG_BASICAUTH_USERNAME: your_username # 替换为你的用户名ME_CONFIG_BASICAUTH_PASSWORD: your_password # 替换为你的密码ME_CONFIG_SERVER_ADDR: 127.0.0.1 # 限制只允许本地访问
使用步骤
把
init-mongo.js
放在和docker-compose.yml
同一目录启动:
docker-compose up -d
第一次启动时,MongoDB 会执行
init-mongo.js
:创建数据库
myapp
建
users
和accounts
集合插入一些初始化数据
- 打开浏览器访问:
http://localhost:8081
就能看到 Mongo Express 管理界面 ✅
📌 说明:MongoDB 数据依旧会保存在
./mongo-data
默认登录就是
admin/ pass
mongo-express
会自动连到mongodb
服务
⚠️ 注意:
初始化脚本 只会在容器第一次启动且数据目录为空时执行。
如果你已经跑过一次,需要先清掉数据目录:
docker-compose down -v
这样 MongoDB 的 root 用户就是:
用户名:
root
密码:
123456
连接地址:
mongodb://root:123456@localhost:27017
进入容器并打开 mongosh
docker exec -it my-mongo mongosh -u root -p 123456
📌 常见操作命令
1. 查看所有数据库
show dbs
📌 会显示已有的数据库,例如:
admin 40.00 KiB
config 72.00 KiB
local 72.00 KiB
myapp 100.00 KiB
2. 切换数据库(没有会自动创建)
use myapp
👉 进入 myapp
数据库。
3. 查看当前数据库
db
👉 输出当前数据库名字,比如:
myapp
4. 查看当前数据库里的所有集合
show collections
👉 例如:
users accounts
5. 查看所有用户
在 admin
数据库 里管理用户。先切换到 admin:
use admin
查看所有用户:
db.getUsers()
输出类似:
[ { "_id": "admin.root", "user": "root", "db": "admin", "roles": [ { "role": "root", "db": "admin" } ] } ]
6. 查询集合里的数据
查询所有文档
db.users.find()
格式化输出
db.users.find().pretty()
查询条件(例子:用户名是 alice)
db.users.find({ username: "alice" })
7. 插入数据
db.users.insertOne({ username: "charlie", email: "charlie@example.com", role: "user" })
8. 删除数据
db.users.deleteOne({ username: "bob" })
9. 更新数据
db.users.updateOne( { username: "alice" }, { $set: { role: "superadmin" } } )
10. 查看集合索引
db.users.getIndexes()
✅ 这几个命令基本覆盖了你日常开发时 建库 → 切库 → 查表 → 插入/更新/删除数据 → 管理用户 的常见需求。
下面把 MongoDB Shell(mongosh)常用命令速查直接原样贴出来(含“怎么建库”的正确做法)。
⚠️ 提醒:MongoDB 没有独立的“create database”命令。做法是:
use 库名
之后 创建集合或插入文档,库就会真正创建。
# =========================
# 连接(Docker 容器里)
# =========================
docker exec -it my-mongo mongosh -u root -p 123456# 也可以用连接串(本机/外部):
mongosh "mongodb://root:123456@localhost:27017/admin"
# 先连到 admin,再切到业务库:
use myapp# =========================
# 数据库相关
# =========================
show dbs # 查看所有数据库
db # 查看当前数据库名
use myapp # 切换数据库(不存在时只是切换上下文)# ——「建库」正确姿势(任意一种都会真正创建数据库)——
use myapp
db.createCollection("users") # 方式1:创建集合
# 或
db.temp.insertOne({a:1}) # 方式2:插入任意文档(会自动建库+集合)db.dropDatabase() # 删除当前数据库(慎用)# =========================
# 集合(表)管理
# =========================
show collections # 列出所有集合
db.createCollection("users") # 新建集合
db.users.renameCollection("members") # 重命名集合
db.users.drop() # 删除集合# =========================
# 文档 CRUD
# =========================
db.users.insertOne({username:"alice", role:"admin"})
db.users.insertMany([{username:"bob"},{username:"charlie"}])db.users.find() # 查询全部
db.users.find({username:"alice"}) # 条件查询
db.users.find({}, {username:1, _id:0}) # 投影(只要某些字段)
#在 MongoDB 中,db.users.find({}, {username:1, _id:0})
#这个查询中 _id 没有返回,是因为你显式指定了 _id:0,这表示排除 _id 字段。
#MongoDB 的投影(projection)规则是:
#字段名:1 表示包含该字段
#字段名:0 表示排除该字段
#而 _id 字段是一个特殊情况:
#它默认会被包含在查询结果中,即使你没有显式指定 _id:1
#只有当你显式指定 _id:0 时,才会排除它db.users.find().sort({username:1}).limit(10).skip(20) # 排序/分页db.users.updateOne({username:"alice"}, {$set:{role:"superadmin"}})
db.users.updateMany({role:"user"}, {$inc:{score:1}})
db.users.replaceOne({_id:ObjectId("...")}, {username:"new"})db.users.deleteOne({username:"bob"})
db.users.deleteMany({role:"temp"})db.users.countDocuments({role:"admin"}) # 计数# =========================
# 索引
# =========================
db.users.createIndex({username:1}, {unique:true}) # 唯一索引
db.users.createIndex({role:1, username:1}) # 复合索引
db.users.getIndexes() # 查看索引
db.users.dropIndex("role_1_username_1") # 删除某个索引
db.users.dropIndexes() # 删除所有二级索引(慎用)# =========================
# 聚合(Aggregation)常用模板
# =========================
db.users.aggregate([{$match: {role: "user"}}, # 过滤{$group: {_id: "$role", cnt: {$sum: 1}}},# 分组计数{$sort: {cnt: -1}}, # 排序{$limit: 10} # 取前10
])# =========================
# 用户与权限(需在 admin 库)
# =========================
use admin
db.getUsers() # 查看所有用户
db.createUser({user: "appuser",pwd: "123456",roles: [{role:"readWrite", db:"myapp"}]
})
db.updateUser("appuser", {roles:[{role:"read", db:"myapp"}]})
db.grantRolesToUser("appuser", [{role:"readWrite", db:"myapp"}])
db.revokeRolesFromUser("appuser", [{role:"readWrite", db:"myapp"}])
db.dropUser("appuser")# 常用内置角色举例:
# read, readWrite, dbAdmin, userAdmin
# clusterAdmin(集群级,慎用)
# root(最高权限,慎用)# =========================
# 实用命令
# =========================
db.stats() # 当前库统计信息
db.users.stats() # 集合统计信息
db.version() # 服务器版本
show roles # 查看角色(在 admin)
show users # 查看用户(在当前库)# =========================
# 连接串小技巧(authSource)
# =========================
# 用 admin 创建的 root 账号访问 myapp 时,常见报错是认证失败;
# 请在连接串加上 ?authSource=admin
# 例:
# mongodb://root:123456@localhost:27017/myapp?authSource=admin
MongoDB 查询进阶速查表
# =========================
# 1. 条件查询运算符
# =========================
db.users.find({ age: { $gt: 18 } }) # > 18
db.users.find({ age: { $gte: 18 } }) # >= 18
db.users.find({ age: { $lt: 30 } }) # < 30
db.users.find({ age: { $lte: 30 } }) # <= 30
db.users.find({ age: { $ne: 20 } }) # != 20db.users.find({ role: { $in: ["admin", "user"] } }) # in
db.users.find({ role: { $nin: ["guest"] } }) # not indb.users.find({ $or: [ {role:"admin"}, {age:{$lt:18}} ] }) # OR 查询
db.users.find({ $and: [ {age:{$gte:18}}, {age:{$lte:30}} ] }) # AND 查询# =========================
# 2. 正则 & 模糊查询
# =========================
db.users.find({ username: /alice/ }) # 模糊包含 "alice"
db.users.find({ username: /^a/ }) # 以 a 开头
db.users.find({ username: /e$/ }) # 以 e 结尾
db.users.find({ email: { $regex: ".*@gmail.com$" } }) # 正则完整写法# =========================
# 3. 投影(只取某些字段)
# =========================
db.users.find({}, { username:1, email:1, _id:0 })# =========================
# 4. 排序 & 分页
# =========================
db.users.find().sort({ age: -1 }) # 按年龄降序
db.users.find().skip(20).limit(10) # 跳过20条,取10条
db.users.find().sort({age:-1}).skip(0).limit(5) # 排序 + 前5条# =========================
# 5. 聚合(Aggregation)
# =========================
# 统计每个角色有多少用户
db.users.aggregate([{ $group: { _id: "$role", count: { $sum: 1 } } }
])# 统计平均年龄
db.users.aggregate([{ $group: { _id: null, avgAge: { $avg: "$age" } } }
])# 按角色分组,统计平均年龄
db.users.aggregate([{ $group: { _id: "$role", avgAge: { $avg: "$age" } } }
])# 查找年龄大于18的用户,并按年龄降序,只取前5个
db.users.aggregate([{ $match: { age: { $gt: 18 } } },{ $sort: { age: -1 } },{ $limit: 5 }
])# =========================
# 6. 去重(distinct)
# =========================
db.users.distinct("role") # 去重查询字段值# =========================
# 7. 常见更新技巧
# =========================
db.users.updateOne({ username:"alice" }, { $set: { age: 25 } }) # 修改字段
db.users.updateOne({ username:"bob" }, { $unset: { email: "" } }) # 删除字段
db.users.updateOne({ username:"bob" }, { $inc: { score: 5 } }) # 数字自增
db.users.updateOne({ username:"bob" }, { $push: { tags: "vip" } })# 数组 push
db.users.updateOne({ username:"bob" }, { $addToSet: { tags: "vip" } }) # 数组去重添加
db.users.updateOne({ username:"bob" }, { $pull: { tags: "old" } })# 从数组移除值# =========================
# 8. 文档计数
# =========================
db.users.countDocuments({ role:"admin" }) # 统计满足条件的数量
📌 总结:
基本查询:
$gt/$lt/$in/$or/$regex
分页排序:
.sort().skip().limit()
聚合管道:
$match
+$group
+$sort
+$limit
去重:
distinct
更新操作符:
$set
/$unset
/$inc
/$push
/$pull
/$addToSet
MongoDB 聚合管道(Aggregation Pipeline)进阶清单
# =========================
# 1. 基础:过滤 + 分组 + 统计
# =========================
# 按角色统计用户数量
db.users.aggregate([{ $group: { _id: "$role", count: { $sum: 1 } } }
])# 按角色统计平均年龄
db.users.aggregate([{ $group: { _id: "$role", avgAge: { $avg: "$age" } } }
])# =========================
# 2. 排序 & 限制
# =========================
# 查找年龄 > 18 的前 5 个用户(按年龄降序)
db.users.aggregate([{ $match: { age: { $gt: 18 } } },{ $sort: { age: -1 } },{ $limit: 5 }
])# =========================
# 3. 投影 & 字段重命名
# =========================
# 只保留 username 和 email,并重命名 email -> contact
db.users.aggregate([{ $project: { username: 1, contact: "$email", _id: 0 } }
])# =========================
# 4. 字段计算
# =========================
# 增加一个新字段 isAdult(true/false)
db.users.aggregate([{ $addFields: { isAdult: { $gte: ["$age", 18] } } }
])# 年龄换算成年份(假设 age 表示岁数)
db.users.aggregate([{ $project: { username: 1, birthYear: { $subtract: [2025, "$age"] } } }
])# =========================
# 5. 多表关联($lookup)
# =========================
# users 表 和 accounts 表关联
db.users.aggregate([{ $lookup: {from: "accounts", # 关联的集合localField: "username", # 当前集合字段foreignField: "user", # 关联集合字段as: "accountInfo" # 输出字段名}}
])# =========================
# 6. 拆分数组($unwind)
# =========================
# 用户文档里有 tags: ["vip", "premium"]
db.users.aggregate([{ $unwind: "$tags" }, # 每个 tag 拆成一行{ $group: { _id: "$tags", count: { $sum: 1 } } }
])# =========================
# 7. 分组统计 + 条件过滤
# =========================
# 按角色统计平均年龄,但只看 count > 2 的角色
db.users.aggregate([{ $group: { _id: "$role", avgAge: { $avg: "$age" }, count: { $sum: 1 } } },{ $match: { count: { $gt: 2 } } }
])# =========================
# 8. 多阶段管道综合示例
# =========================
# 找出余额最高的前 3 个用户(users + accounts 联合查询)
db.users.aggregate([{ $lookup: {from: "accounts",localField: "username",foreignField: "user",as: "accountInfo"}},{ $unwind: "$accountInfo" },{ $project: { username: 1, balance: "$accountInfo.balance", _id: 0 } },{ $sort: { balance: -1 } },{ $limit: 3 }
])
🔑 常用聚合阶段速记
阶段 | 作用 |
---|---|
$match | 过滤文档(相当于 WHERE ) |
$group | 分组统计(相当于 GROUP BY ) |
$sort | 排序 |
$limit | 限制条数 |
$skip | 跳过条数(分页用) |
$project | 投影、重命名字段 |
$addFields | 新增计算字段 |
$lookup | 关联另一张集合(相当于 SQL JOIN ) |
$unwind | 拆分数组字段为多行 |
$count | 输出统计结果 |
$facet | 一次执行多个子管道(多维统计) |
📊 用这套组合拳,你基本可以在 MongoDB 里实现 报表系统 / 数据分析 的 80% 需求。