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% 需求。