[TOC]


基本信息

MongoDB 是一个 开源的 NoSQL 数据库,用 JSON 风格的文档来存储数据,而不是传统关系型数据库的表和行。


主要特点

  1. 文档型存储

    • 数据以 BSON(二进制 JSON)格式保存,类似:

      1
      2
      3
      4
      5
      {
      "name": "Alice",
      "age": 25,
      "skills": ["Python", "Vue"]
      }
  2. 无固定模式(Schema-less)

    • 同一个集合(collection)里的文档结构可以不同,方便灵活扩展。
  3. 高扩展性

    • 支持 分片(Sharding)副本集(Replica Set),可以水平扩展和高可用。
  4. 查询功能强大

    • 支持丰富的查询语法、聚合管道(Aggregation Pipeline)、地理位置查询等。
  5. 适合大数据和快速开发

    • 常用于日志存储、实时分析、内容管理、物联网等场景。

基本概念对比(与 MySQL 类比)

MySQL MongoDB
数据库 (Database) 数据库 (Database)
表 (Table) 集合 (Collection)
行 (Row) 文档 (Document)
列 (Column) 字段 (Field)

简单操作示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 连接 MongoDB
mongo

# 切换/创建数据库
use mydb

# 插入数据
db.users.insert({name: "Alice", age: 25})

# 查询数据
db.users.find({age: {$gt: 20}})

# 更新数据
db.users.update({name: "Alice"}, {$set: {age: 26}})

# 删除数据
db.users.remove({name: "Alice"})

我给你按清单的方式整理一下 MongoDB 的 优缺点应用场景,方便快速理解。


MongoDB 的 优缺点应用场景

优点

  1. 灵活的数据结构
    • 无需预先定义字段结构,适应需求变化快的项目。
  2. 文档型存储,直观易读
    • 数据以 JSON/BSON 格式保存,前后端交互方便。
  3. 高可扩展性
    • 分片(Sharding)支持水平扩展,适合海量数据。
  4. 高可用性
    • 副本集(Replica Set)保证数据冗余和自动故障切换。
  5. 查询和聚合功能强
    • 内置复杂查询、索引、聚合管道,数据处理灵活。
  6. 开发效率高
    • 无需繁琐的表设计,数据结构变动无需迁移表结构。

缺点

  1. 事务支持不如关系型数据库
    • 虽然 4.0 以后支持多文档事务,但性能不如 MySQL。
  2. 数据占用空间较大
    • BSON 比 JSON 更占空间,存储成本可能增加。
  3. 过度灵活可能导致数据不规范
    • 如果不做好约束,容易出现字段不统一、数据混乱。
  4. 复杂关联查询性能差
    • 不擅长多表(多集合)复杂 JOIN。
  5. 内存占用高
    • 需要较多内存来保证索引和性能。

典型应用场景

  1. 内容管理系统(CMS)
    • 博客、新闻、产品展示网站等,数据结构灵活多变。
  2. 大数据实时分析
    • 日志系统、行为数据分析(如 ELK 替代方案)。
  3. 物联网(IoT)数据存储
    • 设备上传的数据格式不统一,适合文档型存储。
  4. 地理位置应用
    • 位置检索(附近的人、附近的店)。
  5. 电商平台
    • 商品信息多样、字段不固定(不同商品有不同属性)。
  6. 游戏后台
    • 玩家数据、装备、日志等非结构化数据。
  7. 社交平台
    • 用户动态、评论、消息等。

如果你要存储 结构多变、读写频繁、数据量大 的内容,MongoDB 很合适;
如果你要 事务性强、结构固定、数据关系复杂,MySQL 会更好。

docker部署

准备工作

准备配置文件与目录结构

image-20250815162323252

./conf/mongod.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
storage:
dbPath: /data/db

systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log

net:
port: 27017
bindIp: 0.0.0.0

processManagement:
fork: false
timeZoneInfo: /usr/share/zoneinfo

security:
authorization: enabled

运行 MongoDB 容器

1
2
3
4
5
6
7
8
9
10
11
docker run -d \
--name mongodb \
-p 27017:27017 \
-v /data/soft/mongo/data:/data/db \
-v /data/soft/mongo/conf/mongod.conf:/etc/mongod.conf \
-v /data/soft/mongo/logs:/var/log/mongodb \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=123456 \
-e TZ=Asia/Shanghai \
mongo:latest \
--config /etc/mongod.conf

参数说明:

  • --name mongodb:容器名称
  • -p 27017:27017:映射端口
  • -v /root/mongo/data:/data/db:持久化数据到宿主机
  • -e MONGO_INITDB_ROOT_USERNAME:管理员用户名
  • -e MONGO_INITDB_ROOT_PASSWORD:管理员密码
  • mongo:latest:镜像名

验证容器运行

1
docker ps

image-20250815162957335


连接 MongoDB

进入容器:

1
docker exec -it mongodb mongosh -u admin -p 123456

或者在宿主机直接用客户端连接:

1
mongodb://admin:123456@<宿主机IP>:27017

使用python测试

需要安装 pymongo库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from pymongo import MongoClient

# 构造连接字符串
uri = "mongodb://admin:123456@192.168.72.11:27017/mydb?authSource=admin"

# 创建客户端
client = MongoClient(uri)

# 选择数据库
db = client["regendb"]

# 选择集合
users = db["users"]

# 查询全部
for user in users.find():
print(user)

# 插入一条数据
users.insert_one({"name": "regen", "age": 25})

# 查询一条数据
print(users.find_one({"name": "Alice"}))

image-20250815164942223

一键安装脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/bin/bash
set -e

# =========================
# Docker 安装 MongoDB 7.0.6 脚本
# =========================
#
# 脚本功能:
# 1. 尝试 Docker 拉取 MongoDB 7.0.6 镜像
# 2. 尝试导入本地镜像(mongo7.0.6.tar)
# 3. 创建数据、配置、日志目录,并设置权限
# 4. 生成默认配置文件 mongod.conf
# 5. 启动 MongoDB 容器,并设置管理员账号密码、端口、时区
# 6. 检查容器是否成功启动
#
# 适用场景:
# - 无网络环境下使用 Docker 安装 MongoDB 7.0.6
# - 需要快速部署 MongoDB 7.0.6 容器,并支持外部访问
#
# 可配置变量:
# IMAGE_FILE MongoDB 镜像 tar 包路径
# IMAGE_NAME Docker 镜像名称
# CONTAINER_NAME 容器名称
# MONGO_PORT MongoDB 端口
# MONGO_USER 管理员用户名
# MONGO_PASSWORD 管理员密码
# TZ 容器时区
# BASE_DIR 数据、配置、日志基础目录
#
# 使用方法:
# 1. 确保 /resources/mongo7.0.6.tar 文件存在
# 2. 执行脚本:sudo bash /scripts/local-docker-mongo.sh
# 3. 查看容器状态:docker ps
# 4. 查看日志:docker logs $CONTAINER_NAME



# =========================
# 可配置参数
# =========================
IMAGE_FILE="/resources/mongo7.0.6.tar"
IMAGE_NAME="mongo:7.0.6"
CONTAINER_NAME="mongodb"
MONGO_PORT=27017
MONGO_USER="admin"
MONGO_PASSWORD="Z3ACxCMS"
TZ="Asia/Shanghai"

# 数据、配置、日志目录
BASE_DIR="/data/soft/mongo"
DATA_DIR="$BASE_DIR/data"
CONF_DIR="$BASE_DIR/conf"
LOGS_DIR="$BASE_DIR/logs"

# =========================
# 创建目录结构
# =========================
echo "创建目录..."
mkdir -p "$DATA_DIR" "$CONF_DIR" "$LOGS_DIR"
# 设置日志目录权限,保证容器可写
chown -R 999:999 "$LOGS_DIR"

if docker pull "$IMAGE_NAME"; then
echo "镜像 $IMAGE_NAME 拉取成功,跳过导入"
else
echo "镜像 $IMAGE_NAME 拉取失败,尝试导入本地镜像 $IMAGE_FILE ..."
if docker image inspect "$IMAGE_NAME" >/dev/null 2>&1; then
echo "镜像 $IMAGE_NAME 已存在,跳过导入"
else
LOADED_IMAGE=$(docker load -i "$IMAGE_FILE" | awk -F': ' '/Loaded image:/ {print $2}')
echo "加载完成,原始镜像: $LOADED_IMAGE"

docker tag "$LOADED_IMAGE" "$IMAGE_NAME"
echo "镜像已重命名为 $IMAGE_NAME"
fi
fi

# =========================
# 创建默认配置文件
# =========================
CONF_FILE="$CONF_DIR/mongod.conf"
echo "创建默认配置文件 $CONF_FILE ..."
cat > "$CONF_FILE" <<EOF
storage:
dbPath: /data/db

systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log

net:
port: $MONGO_PORT
bindIp: 0.0.0.0

processManagement:
fork: false
timeZoneInfo: /usr/share/zoneinfo

security:
authorization: enabled
EOF


# =========================
# 启动容器
# =========================
echo "启动 MongoDB 容器..."
CONTAINER_ID=$(docker run -d \
--name "$CONTAINER_NAME" \
--restart=unless-stopped \
-p $MONGO_PORT:27017 \
-v "$DATA_DIR":/data/db \
-v "$CONF_FILE":/etc/mongod.conf \
-v "$LOGS_DIR":/var/log/mongodb \
-e MONGO_INITDB_ROOT_USERNAME="$MONGO_USER" \
-e MONGO_INITDB_ROOT_PASSWORD="$MONGO_PASSWORD" \
-e TZ="$TZ" \
$IMAGE_NAME \
--config /etc/mongod.conf) || {
echo "容器启动失败!请检查配置或镜像"
exit 1
}

# =========================
# 检查容器状态
# =========================
if [ "$(docker ps -q -f id=$CONTAINER_ID)" ]; then
echo "MongoDB 容器已启动,容器名:$CONTAINER_NAME"
docker ps --filter "id=$CONTAINER_ID"
else
echo "MongoDB 容器启动失败,请查看日志:docker logs $CONTAINER_NAME"
exit 1
fi

宿主机安装

包管理器安装

1
sudo dnf install -y mongodb-org

离线包安装

准备好离线包

1
2
# 在有网的机器下载
dnf download --resolve mongodb-org

scp或者xftp复制到某个文件夹后

1
dnf install -y ./*.rpm

配置文件(可选)

修改端口绑定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# mongod.conf

# for documentation of all options, see:
# http://docs.mongodb.org/manual/reference/configuration-options/

# where to write logging data.
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log

# Where and how to store data.
storage:
dbPath: /var/lib/mongo
journal:
enabled: true
# engine:
# wiredTiger:

# how the process runs
processManagement:
timeZoneInfo: /usr/share/zoneinfo

# network interfaces
net:
port: 27017
bindIp: 0.0.0.0


#security:

#operationProfiling:

#replication:

#sharding:

## Enterprise-Only Options

#auditLog:

#snmp:

启动

1
2
3
4
sudo systemctl start mongod
sudo systemctl enable mongod
sudo systemctl status mongod

初始化

1
2
3
4
5
6
7
mongosh
use admin
db.createUser({
user: "admin",
pwd: "123456",
roles: [ { role: "root", db: "admin" } ]
})

一键安装脚本

需要提前准备好安装包到对应的目录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/bin/bash


# ============================
# MongoDB 离线安装脚本
# ============================
#
# 脚本功能:
# 1. 离线安装 MongoDB RPM 包
# 2. 自动生成或修改默认配置文件
# 3. 修改 bindIp 为 0.0.0.0,使外部可访问
# 4. 创建数据目录和日志目录,并设置权限
# 5. 启动 MongoDB 服务并启用开机自启
# 6. 创建管理员账号及密码
#
# 适用场景:
# - 无网络环境下,需要离线安装 MongoDB
# - Linux 系统使用 DNF/YUM 包管理的环境(如 CentOS 8 / RHEL 8 / Fedora)
#
# 前置条件:
# - 已将 MongoDB RPM 包放在 /data/resources/mongo 目录
# - 有 sudo 权限
#

# 注意事项:
# - 如果管理员账号已存在,会报错
# - 数据目录默认 /var/lib/mongo,日志目录默认 /var/log/mongodb
# - 可根据需要修改端口和管理员账号密码变量
#
# 使用方法:
# 1. 将脚本放在任意目录,例如 /scripts/local-install-mongo.sh
# 2. 修改顶部变量 MONGO_RPM_DIR、ADMIN_USER、ADMIN_PASS、PORT
# 3. 执行:sudo bash /scripts/local-install-mongo.sh

set -e

# 配置变量
MONGO_RPM_DIR="/data/resources/mongo"
CONF_FILE="/etc/mongod.conf"
ADMIN_USER="admin"
ADMIN_PASS="123456"
PORT=27017

echo "==========================="
echo "MongoDB 离线安装脚本-开始"
echo "==========================="

# 1️⃣ 安装 RPM 包
echo "安装 MongoDB RPM 包..."
sudo dnf install -y $MONGO_RPM_DIR/*.rpm

# 2️⃣ 修改配置文件
echo "配置 mongod.conf..."
if [ ! -f "$CONF_FILE" ]; then
echo "mongod.conf 不存在,创建默认配置..."
cat > "$CONF_FILE" <<EOF
storage:
dbPath: /var/lib/mongo

systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log

net:
port: $PORT
bindIp: 127.0.0.1

processManagement:
fork: true
timeZoneInfo: /usr/share/zoneinfo

security:
authorization: enabled
EOF
fi

# 修改 bindIp 为 0.0.0.0
sed -i "s/bindIp:.*/bindIp: 0.0.0.0/" "$CONF_FILE"

# 3️⃣ 确保数据目录和日志目录存在且权限正确
DATA_DIR=$(grep 'dbPath' $CONF_FILE | awk '{print $2}')
LOG_FILE=$(grep 'path:' $CONF_FILE | grep mongodb | awk '{print $2}')
LOG_DIR=$(dirname "$LOG_FILE")

mkdir -p "$DATA_DIR" "$LOG_DIR"
chown -R mongod:mongod "$DATA_DIR" "$LOG_DIR"
chmod 700 "$DATA_DIR"
chmod 755 "$LOG_DIR"

# 4️⃣ 启动 MongoDB 服务
echo "启动 MongoDB..."
sudo systemctl enable mongod
sudo systemctl start mongod

# 等待服务启动
sleep 5

# 5️⃣ 创建管理员账号
echo "创建管理员账号 $ADMIN_USER..."
mongo --eval "db.getSiblingDB('admin').createUser({user: '$ADMIN_USER', pwd: '$ADMIN_PASS', roles:[{role:'root', db:'admin'}]});"

echo "MongoDB 安装完成,管理员账号: $ADMIN_USER 密码: $ADMIN_PASS"
echo "默认端口: $PORT, 监听所有 IP: 0.0.0.0"
echo "可以使用: sudo systemctl status mongod 查看服务状态"

image-20250815164416267

image-20250815164358826

mongo基础


1. 数据库相关

功能 命令
显示所有数据库 show dbs
切换数据库(不存在会自动创建) use mydb
查看当前数据库 db
删除当前数据库 db.dropDatabase()

2. 集合(表)相关

功能 命令
显示所有集合 show collections
创建集合 db.createCollection("users")
删除集合 db.users.drop()

3. 数据(文档)操作

插入

1
2
3
4
5
db.users.insertOne({name: "Alice", age: 25})
db.users.insertMany([
{name: "Bob", age: 30},
{name: "Charlie", age: 28}
])

查询

1
2
3
4
5
db.users.find()                          // 查询全部
db.users.find().pretty() // 格式化输出
db.users.find({name: "Alice"}) // 条件查询
db.users.find({age: {$gt: 25}}) // 年龄大于25
db.users.find({}, {name: 1, _id: 0}) // 只返回 name 字段

更新

1
2
3
4
5
6
7
8
9
db.users.updateOne(
{name: "Alice"},
{$set: {age: 26}}
)

db.users.updateMany(
{age: {$gt: 25}},
{$set: {status: "active"}}
)

删除

1
2
db.users.deleteOne({name: "Bob"})
db.users.deleteMany({age: {$lt: 20}})

4. 索引

1
2
3
db.users.createIndex({name: 1})        // 升序索引
db.users.getIndexes() // 查看索引
db.users.dropIndex("name_1") // 删除索引

5. 用户与权限

1
2
3
4
5
6
7
8
9
10
// 在 admin 数据库创建超级用户
use admin
db.createUser({
user: "admin",
pwd: "123456",
roles: [{role: "root", db: "admin"}]
})

// 查看当前数据库用户
show users

问题

时区

配置文件里的时区项不能随意修改timeZoneInfo: /usr/share/zoneinfo

如果是docker部署需要在run的时候使用 -e TZ=Asia/Shanghai,如果是宿主机则会(还不清楚)…

不管是docker还是宿主机,这项配置改动了都可能起不来。

Docker 容器中推荐用 -e TZ 方式设置时区,而不是修改 mongod.conf

配置文件修改 timeZoneInfo 只在特殊场景下使用,并且容易出错。