当前位置: 首页 > news >正文

mongoDB学习(docker)

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  # 限制只允许本地访问

使用步骤

  1. init-mongo.js 放在和 docker-compose.yml 同一目录

  2. 启动:

    docker-compose up -d

  3. 第一次启动时,MongoDB 会执行 init-mongo.js

    • 创建数据库 myapp

    • usersaccounts 集合

    • 插入一些初始化数据

  4.  打开浏览器访问:
    • 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% 需求。

http://www.dtcms.com/a/356700.html

相关文章:

  • MYSQL速通(2/5)
  • 【开题答辩全过程】以 基于Spring Boot的网上家庭烹饪学习系统的设计与实现为例,包含答辩的问题和答案
  • 软考-系统架构设计师 办公自动化系统(OAS)详细讲解
  • LeetCode 完全背包 279. 完全平方数
  • 小程序版碰一碰发视频:源码搭建与定制化开发的源头技术解析
  • Java开发MongoDB常见面试题及答案
  • [TG开发]与Reids集成
  • five86: 2靶场渗透
  • LangChain实战(二):环境搭建与Hello World(国内开源模型版)
  • 互联网大厂Java面试:从基础到微服务云原生的深度解析
  • web3简介
  • 克隆态驱动给用户态使用流程
  • Git 8 ,git 分支开发( 切换分支开发,并设置远程仓库默认分支 )
  • 衡石SENSE 6.0技术解析:Workflow到Agent模式如何重塑计算框架
  • 04数据库约束实战:从入门到精通
  • TI-92 Plus计算器:常规计算功能介绍
  • CAN总线(Controller Area Network Bus)控制器局域网总线(二)
  • 动态UI的秘诀:React中的条件渲染
  • 当门禁系统遇上边缘计算,RK3568核心板如何带来智能化变革
  • [vmware][ubuntu]一个linux调用摄像头截图demo
  • 前端vue框架实现反向代理详解
  • 【网弧软著正版】2025最强软著材料AI生成系统,基于GPT5.0
  • 华硕主板 BIOS 提示——GPT header corruption has been detected
  • 港科大开放世界长时域具身导航!LOVON:足式机器人开放词汇目标导航
  • 数据结构 02(线性:顺序表)
  • 第四章 Vue3 + Three.js 实战:GLTF 模型加载与交互完整方案
  • Go初级之五:结构体与方法
  • 二手奢侈品拍照估价上门快递回收小程序开发
  • 前端如何使用canvas实现截图
  • 【前端教程】从零开始学JavaScript交互:7个经典事件处理案例解析