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

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.xdnf.cn/news/18987.html

相关文章:

  • Bert学习笔记
  • HDFS 基本原理与操作流程
  • Python 【深度解析】线程与进程:操作系统中多任务的核心机制
  • 嵌入式第四十一天(数据库)
  • undefined和null
  • 【大模型14】Fine-tuning与大模型优化1
  • HunyuanVideo-Foley视频音效生成模型介绍与部署
  • 【完整源码+数据集+部署教程】胚胎发育阶段检测系统源码和数据集:改进yolo11-SCConv
  • Git 8 ,git 分支开发( 切换分支开发,并设置远程仓库默认分支 )
  • 机器视觉opencv教程(二):二值化、自适应二值化
  • 云计算学习笔记——逻辑卷管理、进程管理、用户提权RAID篇
  • 利用亮数据MCP服务器构建个性化学习情报官智能体
  • 第三章 Vue3 + Three.js 实战:用 OrbitControls 实现相机交互与 3D 立方体展示
  • 《应用密码学》——基础知识及协议结构模块(笔记)
  • 第2.1节:AI大模型之GPT系列(GPT-3、GPT-4、GPT-5)
  • 箭头函数和普通函数的区别
  • websocket的应用
  • 【物联网】什么是 DHT11(数字温湿度传感器)?
  • 为什么不能创建泛型数组?
  • 【计算机408计算机网络】第三章:自底向上五层模型之数据链路层
  • 轮廓周长,面积,外界圆,外界矩形近似轮廓和模板匹配和argparse模块实现代码参数的动态配置
  • STL 深度解析之vector【C++每日一学】
  • AI接管浏览器:Anthropic发布Claude for Chrome,是效率革命还是安全噩梦?
  • 科技大会用了煽情BGM
  • Linux网络基础1(一)之计算机网络背景
  • 解密 Vue 3 shallowRef:浅层响应式 vs 深度响应式的性能对决
  • 答案引擎优化(AEO)制胜策略:抢占AI Overviews流量红利
  • 【基于hyperledger fabric的教育证书管理系统】
  • Maven安装、IDEA集成Maven、依赖管理、单元测试
  • Pinterest自动化 “Pin“得高效