导读

你用过 MySQL 吗?MySQL 的数据存在一张一张的表里——每行必须对齐相同的列。MongoDB 换了一种思路:数据以"文档"为单位存储,每个文档是一段类 JSON 的结构,字段可以自由增减。这篇教程不讲深奥的理论,而是手把手带你装好 MongoDB、学会最常用的增删改查操作,最后回答一个实际问题——什么时候该用 MongoDB 而不是 MySQL。

全程使用 mongosh(MongoDB 官方命令行工具),命令逐行带注释,复制粘贴即可运行。


一、文档模型 vs 关系表:先搞懂"长什么样"

在动手之前,先看 MongoDB 数据长什么样,跟 MySQL 的区别是什么。

下图直观对比了两种存储方式:

文档模型 vs 关系表

MySQL 的思路像 Excel:

  • 所有行必须有相同的列(id、姓名、年龄、邮箱)
  • 想关联用户和地址?得建两张表再用 JOIN 拼起来
  • 结构固定,加个新字段要改表结构(ALTER TABLE)

MongoDB 的思路像一个装满文件夹的柜子:

  • 每个文档是独立的 JSON 块,字段可以完全不同
  • 上面第二个例子中,李四多了个 address 嵌套对象(城市、邮编),张三没有——没问题,各自独立
  • 不需要 JOIN:相关数据直接嵌套在同一个文档里

术语解释JSON(JavaScript Object Notation)是一种轻量级数据格式,用 {} 包起来的键值对,几乎所有编程语言都能直接读写。

这就是 MongoDB 被称为"文档型数据库“的原因——数据的基本单位叫 Document(文档),不是 Row(行)。


二、安装 MongoDB Community

2.1 Linux(Ubuntu / Debian)

以下步骤适用于 Ubuntu 20.04+、Debian 11+、WSL2。

第 1 步:导入 MongoDB 官方 GPG 密钥

# 把 MongoDB 包的签名密钥加入系统信任列表,否则 apt 会报"未认证"错误
sudo apt-get install -y gnupg curl
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | \
  sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor

⚠️ 国内下载慢? MongoDB 官网的 .deb 包下载速度可能很慢。如果超时,可以改用以下两种方式之一:

  • 清华镜像(部分版本):参考 清华大学 MongoDB 镜像站
  • 离线安装:在能联网的机器上下载 .deb 包,拷到目标机器后 sudo dpkg -i mongodb-org_*.deb

第 2 步:添加 apt 源

# 告诉 apt:"去哪里找 MongoDB 安装包"(此处为官方源;国内可替换为镜像)
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | \
  sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list

第 3 步:安装

# 更新本地包索引 → 安装 MongoDB 核心组件(含 mongod 服务端 + mongosh 客户端)
sudo apt-get update
sudo apt-get install -y mongodb-org

2.2 macOS

# Homebrew 是中国开发者常用的 macOS 包管理器(类似 Ubuntu 的 apt)
# 还没装 Homebrew?执行:/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew tap mongodb/brew
brew install [email protected]

2.3 Windows

最省事的方法是用 Chocolatey(Windows 下的包管理器):

# 以管理员身份打开 PowerShell,然后:
choco install mongodb -y

也可以去 MongoDB 官网下载页面 下载安装包。国内用户如果觉得官网下载慢,可以用 ghfast.top 代理 GitHub 加速获取第三方安装器。


三、启动与服务验证

Linux(systemd 系统)

# 启动 MongoDB 服务
sudo systemctl start mongod

# 设置开机自启
sudo systemctl enable mongod

# 查看状态(应显示 active (running))
sudo systemctl status mongod

macOS

# brew 安装的 MongoDB,默认监听 27017 端口
brew services start [email protected]

连接测试

打开一个新的终端窗口,输入:

# 进入 MongoDB 交互式命令行(默认连接 localhost:27017)
mongosh

看到 test> 提示符就说明连接成功了。下面所有命令都在这个交互环境中输入。


四、基础 CRUD:增删改查

CRUD 是数据库操作的四个基本动作:Create(增)、Read(读)、Update(改)、Delete(删)。MongoDB 通过集合(Collection)管理文档——相当于 MySQL 里的"表”,但创建时无需预先定义结构。

4.1 选择数据库 & 创建集合

// 切换到 mydb 数据库(不存在会自动创建,就像第一次打开 Word 自动新建文件)
use mydb

// 手动创建一个名为 users 的集合(实际上不创建也没事——插入第一条数据时 MongoDB 自动帮你建)
db.createCollection("users")
// 返回: { ok: 1 }   ← 表示成功

术语解释集合(Collection) 就是 MongoDB 中一组文档的容器,类似 MySQL 中的"表"。区别在于集合不需要预先声明列结构

4.2 增 — InsertOne / InsertMany

// 【新增单条】插入一个用户文档
db.users.insertOne({
  name: "张三",
  age: 25,
  email: "[email protected]",
  tags: ["前端", "Python"]     // 数组类型,无需预定义
})

// 【新增多条】一次性插入 3 个用户
db.users.insertMany([
  { name: "李四", age: 30, email: "[email protected]", city: "上海" },
  { name: "王五", age: 28, email: "[email protected]", city: "北京" },
  { name: "赵六", age: 35, email: "[email protected]", city: "深圳" }
])

白话解释insertOne 插入单个文档,insertMany 批量插入。注意每个文档的字段可以不一样——李四有 city,张三没有,完全合法。

4.3 读 — Find / FindOne

// 【读全部】查询 users 集合的所有文档
db.users.find()

// 【美化输出】加上 .pretty() 可以更清晰地看到 JSON 格式(可选)
db.users.find().pretty()

// 【读一条】只返回第一个匹配的文档
db.users.findOne({ name: "张三" })

4.4 条件查询 — 查询运算符 $gt / $in

MongoDB 用操作符来构造复杂的查询条件。以下是最常用的两个:

操作符含义类比 SQL
$gtGreater Than,大于>
$gteGreater Than or Equal,大于等于>=
$ltLess Than,小于<
$lteLess Than or Equal,小于等于<=
$in在某个列表中IN (...)
$ne不等于!=
// 【$gt 大于】查找年龄大于 28 岁的用户
db.users.find({ age: { $gt: 28 } })
// 结果: 李四(30)、赵六(35)

// [$gt + $lt 组合] 查找年龄在 26 到 32 之间(不含边界)的用户
db.users.find({ age: { $gt: 26, $lt: 32 } })
// 结果: 王五(28)、李四(30)

// [$in 在列表中] 查找城市为上海或北京的用户
db.users.find({ city: { $in: ["上海", "北京"] } })
// 结果: 李四(上海)、王五(北京)

// [$ne 不等于] 查找城市不为深圳的用户
db.users.find({ city: { $ne: "深圳" } })

// 组合查询:年龄 > 28 AND 城市在上海或北京
db.users.find({
  age: { $gt: 28 },
  city: { $in: ["上海", "北京"] }
})
// 结果: 李四(30岁, 上海)

小白提示:多个字段并列写在 {} 里就是 AND 关系。如果需要 OR,要用 $or 关键字:

db.users.find({ $or: [{ age: { $gt: 32 } }, { city: "上海" }] })

4.5 改 — UpdateOne / UpdateMany

// 【改单条】把张三的年龄改为 26
// $set 操作符 = "只更新指定的字段,不动其他字段"(不加 $set 会把整个文档替换掉!)
db.users.updateOne(
  { name: "张三" },                          // 过滤条件:找谁
  { $set: { age: 26 } }                      // 修改操作:改成什么
)
// 返回: { acknowledged: true, modifiedCount: 1 }  ← 改了 1 条

// 【改多条】把所有用户的 age 加 1($inc = increment,增量增加)
db.users.updateMany(
  { },                                        // {} = 匹配所有文档
  { $inc: { age: 1 } }                        // age 都 +1
)

// 【添加新字段】给所有用户添加 level 字段
db.users.updateMany(
  {},
  { $set: { level: "active" } }
)

// 【数组追加】给李四的 tags 数组追加一个标签($push)
db.users.updateOne(
  { name: "李四" },
  { $push: { tags: "Java" } }
)

重要提醒:不用 $set 直接写 db.users.updateOne({name:"张三"}, {age:99}) 会把张三整个文档替换成 {age: 99}——其他字段全丢了!始终用 $set

4.6 删 — DeleteOne / DeleteMany

// 【删单条】删除名字为王五的用户
db.users.deleteOne({ name: "王五" })
// 返回: { acknowledged: true, deletedCount: 1 }

// 【删多条】删除所有 city 为深圳的用户
db.users.deleteMany({ city: "深圳" })

// 【清空集合】删除 users 集合中的所有文档(保留集合本身)
db.users.deleteMany({})

// 【删除整个集合】相当于 MySQL 的 DROP TABLE
db.users.drop()

// 【切换回 test 库并删库】
use test
db.mydb.dropDatabase()

五、索引:让查询飞起来

什么是索引? 类比字典的目录——没有目录就要一页页翻,有了目录直接定位到页码。MongoDB 的索引也是这样:创建后查询速度大幅提升。

5.1 创建索引

// 【单字段索引】在 name 字段上创建升序索引(1 = 升序,-1 = 降序)
db.users.createIndex({ name: 1 })

// 【多字段复合索引】先按 city 排序,同城市内按 age 排序
db.users.createIndex({ city: 1, age: -1 })

// 【唯一索引】保证 email 字段不重复(类似 MySQL UNIQUE 约束)
db.users.createIndex({ email: 1 }, { unique: true })
// 如果已有重复数据会报错,需要先清理

// 【过期索引】createDate 字段满 30 天后文档自动被删除(TTL 索引)
db.sessions.createIndex({ createDate: 1 }, { expireAfterSeconds: 2592000 })
// 2592000 = 30 × 24 × 3600(秒)

5.2 查看与管理索引

// 查看 users 集合上已有的所有索引
db.users.getIndexes()

// 删除指定名称的索引
db.users.dropIndex("name_1")

// 删除集合上的所有索引(慎用!)
db.users.dropIndexes()

性能建议:常用查询字段、经常做排序的字段都应该建索引。但也别到处建——每个索引都会占用磁盘空间并减慢写入速度。一般建 3~5 个常用索引就够了。


六、聚合管道入门:数据的"流水线加工厂"

聚合管道(Aggregation Pipeline) 是 MongoDB 最强大的功能之一。数据像工厂流水线一样,经过一道道「加工工序」(Stage),每一步都对数据做一次变换。

// 准备一些示例数据(订单文档)
db.orders.insertMany([
  { buyer: "张三", item: "笔记本", amount: 100, city: "上海" },
  { buyer: "李四", item: "鼠标",   amount: 50,  city: "上海" },
  { buyer: "王五", item: "键盘",   amount: 80,  city: "北京" },
  { buyer: "赵六", item: "显示器", amount: 500, city: "深圳" },
  { buyer: "张三", item: "耳机",   amount: 200, city: "上海" }
])

6.1 常用 Stage(加工工序)

Stage作用类比 SQL
$match过滤文档WHERE
$group分组统计GROUP BY
$sort排序ORDER BY
$project挑选/重命名字段SELECT
$limit限制返回数量LIMIT

6.2 实战示例

// 【例1】计算每个城市的消费总额
db.orders.aggregate([
  { $group: {           // 按 city 分组
      _id: "$city",       // 分组依据:$city 表示取文档的 city 字段值
      total: { $sum: "$amount" },  // 累加 amount 字段
      count: { $sum: 1 }            // 计数(每条 +1)
    }
  },
  { $sort: { total: -1 } },          // 按总金额降序排列
  { $project: {                      // 只返回 city 和 total,隐藏 _id
      _id: 0,
      city: "$_id",
      totalAmount: "$total",
      orderCount: "$count"
    }
  }
])
// 结果:
// { city: "上海", totalAmount: 350, orderCount: 3 }
// { city: "深圳", totalAmount: 500, orderCount: 1 }
// { city: "北京", totalAmount: 80,  orderCount: 1 }
// 【例2】找到每个人花费最多的订单(先排序再取首条)
db.orders.aggregate([
  { $sort: { buyer: 1, amount: -1 } },   // 先按买家分组排好序
  { $group: {                             // 取每组的第一条
      _id: "$buyer",
      maxOrder: { $first: "$item" },
      maxAmount: { $first: "$amount" }
    }
  },
  { $sort: { maxAmount: -1 } }
])
// 结果: 赵六买显示器花了 500 最多
// 【例3】只查金额 > 100 的订单(用 $match 提前过滤减少流量)
db.orders.aggregate([
  { $match: { amount: { $gt: 100 } } },   // 先过滤
  { $group: {                              // 再分组统计
      _id: "$buyer",
      totalSpent: { $sum: "$amount" }
    }
  }
])

小白提示:管道写法 [ {...}, {...} ] ——就像 Unix 命令行的 cmd1 | cmd2 | cmd3,数据从左到右流过每个阶段。先用 $match 过滤掉不必要的数据,后面阶段的压力就会小很多。

如果你想快速搭建带有 AI 对话界面的应用,也可以用云服务——比如 云间 API 中转站 支持 OpenAI 兼容和 Anthropic 兼容接口,接入简单,香港节点国内直连,适合不想折腾服务器基础设施的同学。


七、备份与恢复:别丢数据

生产环境一定要定期备份。MongoDB 自带两个工具:mongodump(备份)和 mongorestore(恢复)。

7.1 备份

# 将整个 mydb 数据库导出到 ./backup/mydb 目录
mongodump --db mydb --out ./backup

# 也可以只备份指定的集合
mongodump --db mydb --collection users --out ./backup

# 如果是远程服务器:
mongodump --host 192.168.1.100 --port 27017 --db mydb --out ./backup

# 压缩备份(--gzip 节省磁盘空间,约 70% 体积)
mongodump --db mydb --out ./backup --gzip

备份完成后会在 ./backup/mydb/ 下生成 .bson(二进制数据)和 .json(元数据)文件。

7.2 恢复

# 将备份恢复到 MongoDB(会覆盖现有同名数据库)
mongorestore --db mydb ./backup/mydb

# 只恢复 users 集合
mongorestore --db mydb --collection users ./backup/mydb/users.bson

# gzip 压缩过的备份加 --gzip 参数
mongorestore --db mydb --gzip ./backup/mydb

7.3 定时备份脚本示例

#!/bin/bash
# 每天凌晨 2 点备份,文件名带日期戳
BACKUP_DIR="/data/backups/mongodb/$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"
mongodump --db mydb --out "$BACKUP_DIR" --gzip

# 保留最近 7 天的备份
find /data/backups/mongodb/ -maxdepth 1 -mtime +7 -exec rm -rf {} \;

crontab 配置crontab -e 加入一行:0 2 * * * /root/scripts/mongo-backup.sh


八、什么时候选 MongoDB 而不是 MySQL?

这是选型的核心问题。下面的场景更适合 MongoDB:

场景MongoDB 优势MySQL 劣势
数据结构经常变随时加字段,不影响已有数据需要 ALTER TABLE,可能锁表
内容管理系统(CMS)文章、评论、标签天然嵌套在一个文档里需要多表 JOIN,复杂且慢
实时数据分析聚合管道灵活,可随时加新维度临时加聚合维度要改查询甚至改表
海量日志/埋点写入速度快,可 TTL 自动过期大表维护成本高(分区、归档)
地理位置查询内置 2dsphere 索引,原生支持需要额外插件或复杂计算
快速原型开发先跑起来再调整结构要先设计好 ER 图、建好表

这些场景还是选 MySQL:

场景原因
金融交易系统MySQL 事务支持成熟(ACID 严格保证)
强一致性要求MongoDB 的弱一致性配置不适合财务对账
复杂的多表关联查询JOIN 能力 MySQL 远胜
团队熟悉度如果团队全是 SQL 专家,强行上 NoSQL 会增加学习成本

一句话原则结构化、强一致、重关联 → MySQL灵活多变、快写快读、嵌套数据 → MongoDB。两者并不互斥——很多公司同时使用:MySQL 管业务订单,MongoDB 管日志和分析。


九、小结

本篇覆盖了 MongoDB 的完整入门路径:

步骤关键命令用途
安装apt-get install mongodb-org装上服务端和客户端
insertOne() / insertMany()写入文档
find() + $gt/$in 等操作符查询符合条件的文档
updateOne() + $set/$inc精准修改字段
deleteOne() / deleteMany()移除文档
索引createIndex({field: 1})加速查询
聚合aggregate([{ $match }, { $group }])数据分析流水线
备份mongodump / mongorestore数据安全兜底

MongoDB 上手门槛低——没有表结构的概念意味着你可以「先跑起来再说」,这对初学者和对敏捷开发有需求的团队非常友好。当然,深入使用时还需要了解复制集(Replica Set)、分片(Sharding)等高级话题,那些留到下一篇教程再聊。如果你不想在本机搭建开发环境,也可以直接用云服务,比如 云间 API 中转站 支持 OpenAI 兼容和 Anthropic 兼容接口,香港节点国内直连、价格从 0.05 倍起,适合快速验证想法的同学。


附录:一键安装脚本

下面是完整的自动安装脚本,复制即用。脚本会检测你的网络环境(国内/国外),自动选择合适的软件源,并包含超时和回退机制。

公开源码,欢迎审查——不放心可以先复制给任何 AI 判断。

Linux / macOS / WSL(Bash 版)

#!/usr/bin/env bash
set -u
# ============================================================
#  MongoDB 一键安装与验证脚本(macOS / Linux / WSL)
#  公开源码,欢迎审查 —— 不放心可先复制给 AI 判断
#  默认配置:云间 API 中转站(https://cloudzone-api.cyou/)
# ============================================================

GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; CYAN='\033[0;36m'; NC='\033[0m'
info()  { echo -e "${GREEN}[INFO]${NC} $1"; }
warn()  { echo -e "${YELLOW}[WARN]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1"; }
step()  { echo -e "${CYAN}[STEP]${NC} $1"; }

detect_network() {
  step "检测网络环境(国内 / 国外)..."
  if curl -fsI --max-time 5 "https://claude.ai" >/dev/null 2>&1; then
    info "可直连 claude.ai,判定为海外网络"
    echo "overseas"
  else
    warn "无法直连 claude.ai,判定为国内网络环境(将优先使用镜像源)"
    echo "domestic"
  fi
}

check_root() {
  # 部分命令需要 sudo 权限(如 apt-get 安装、systemctl 管理服务)
  if [ "$(id -u)" -ne 0 ]; then
    error "此脚本需要 root 权限运行。请执行:sudo bash $0"
    exit 1
  fi
  return 0
}

install_linux() {
  local net="$1"
  step "在 Linux (apt) 上安装 MongoDB Community 7.0 ..."

  info "安装必要依赖(gnupg, curl)..."
  if ! apt-get install -y gnupg curl >/dev/null 2>&1; then
    error "依赖安装失败。请检查网络连接后重试。"
    return 1
  fi

  info "导入 MongoDB 官方 GPG 密钥 ..."
  local key_url="https://www.mongodb.org/static/pgp/server-7.0.asc"
  if [ "$net" = "domestic" ]; then
    key_url="https://mirrors.aliyun.com/mongodb/static/pgp/server-7.0.asc"
  fi
  if ! curl -fsSL --max-time 30 "$key_url" | gpg --dearmor -o /usr/share/keyrings/mongodb-server-7.0.gpg 2>/dev/null; then
    warn "官方密钥导入失败,尝试备用源 ..."
    if ! curl -fsSL --max-time 30 "https://www.mongodb.org/static/pgp/server-7.0.asc" | gpg --dearmor -o /usr/share/keyrings/mongodb-server-7.0.gpg 2>/dev/null; then
      error "GPG 密钥导入失败。请手动下载并导入。"
      return 1
    fi
    info "备用源密钥导入成功"
  fi

  info "添加 MongoDB apt 源 ..."
  # 尝试检测系统发行版代号
  local distro
  distro=$(. /etc/os-release && echo "$UBUNTU_CODENAME" 2>/dev/null || echo "jammy")

  local source_line="deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu ${distro}/mongodb-org/7.0 multiverse"
  if [ "$net" = "domestic" ]; then
    # 国内可使用腾讯云镜像作为备选
    source_line="deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://mirrors.cloud.tencent.com/mongodb/apt/ubuntu ${distro}/mongodb-org/7.0 multiverse"
  fi

  echo "$source_line" | tee /etc/apt/sources.list.d/mongodb-org-7.0.list > /dev/null

  info "更新包索引并安装 MongoDB ..."
  if ! apt-get update -qq >/dev/null 2>&1; then
    warn "主源更新失败,尝试不使用签名的备用源 ..."
    echo "deb https://repo.mongodb.org/apt/ubuntu ${distro}/mongodb-org/7.0 multiverse" \
      | tee /etc/apt/sources.list.d/mongodb-org-7.0-fallback.list
    if ! apt-get update -qq >/dev/null 2>&1; then
      error "apt 更新失败。可能是网络或镜像源问题。"
      error "建议:手动下载 .deb 包安装(https://www.mongodb.com/try/download/community)"
      return 1
    fi
  fi

  if ! apt-get install -y mongodb-org >/dev/null 2>&1; then
    error "MongoDB 安装失败。常见原因:"
    echo "  1. 国内网络慢:改用腾讯云/阿里云镜像(已自动尝试)"
    echo "  2. 系统版本不支持:MongoDB 7.0 需要 Ubuntu 22.04+/Debian 11+"
    echo "  3. 离线安装:下载 .deb 包后执行 sudo dpkg -i mongodb-org_*"
    return 1
  fi

  info "MongoDB 安装完成!版本:$(mongod --version | head -1)"
  return 0
}

install_macos() {
  local net="$1"
  step "在 macOS 上安装 MongoDB ..."

  if ! command -v brew >/dev/null 2>&1; then
    error "未检测到 Homebrew。请先安装:"
    echo "  /bin/bash -c \"\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\""
    return 1
  fi

  info "添加 MongoDB brew tap ..."
  if ! brew tap mongodb/brew 2>/dev/null; then
    warn "tap 可能已存在,继续安装 ..."
  fi

  info "安装 [email protected] ..."
  if ! brew install --query [email protected] >/dev/null 2>&1; then
    warn "已安装,跳过 ..."
  fi

  info "启动 MongoDB 服务 ..."
  brew services start [email protected] 2>/dev/null || true
  info "已完成。验证:mongosh"
  return 0
}

start_mongod() {
  step "确保 MongoDB 服务正在运行 ..."

  if command -v systemctl >/dev/null 2>&1; then
    if ! systemctl is-active --quiet mongod 2>/dev/null; then
      info "启动 mongod 服务 ..."
      sudo systemctl start mongod 2>/dev/null || {
        warn "systemctl 启动失败,尝试直接启动 mongod ..."
        sudo mkdir -p /var/log/mongodb /var/lib/mongodb
        sudo mongod --fork --logpath /var/log/mongodb/mongod.log \
          --bind_ip 127.0.0.1 --port 27017 2>/dev/null || true
      }
    fi
    info "mongod 服务已就绪"
  elif command -v brew >/dev/null 2>&1; then
    brew services list | grep mongodb && info "MongoDB 已在运行" || {
      brew services start [email protected] 2>/dev/null || true
      info "已尝试启动"
    }
  else
    warn "未检测到 systemd 或 brew,请手动启动 mongod。"
    warn "  命令:mongod --dbpath /data/db --port 27017"
  fi
}

verify_install() {
  step "验证 MongoDB 是否可用 ..."

  if ! command -v mongosh >/dev/null 2>&1; then
    error "mongosh 未找到。安装可能不完整。"
    return 1
  fi

  info "等待 MongoDB 服务就绪(最多 15 秒)..."
  for i in $(seq 1 15); do
    if mongosh --eval "db.runCommand('ping')" >/dev/null 2>&1; then
      info "MongoDB 连接成功!"
      return 0
    fi
    sleep 1
  done

  error "MongoDB 连接超时。请检查 mongod 是否正在运行。"
  return 1
}

insert_test_data() {
  step "插入 3 条测试数据用于验证 ..."

  mongosh --quiet --eval '
    use test
    db.verify_test.deleteMany({})
    db.verify_test.insertMany([
      { name: "Alice", age: 22, city: "Beijing" },
      { name: "Bob",   age: 28, city: "Shanghai" },
      { name: "Charlie", age: 35, city: "Shenzhen" }
    ])
    print("插入成功!当前共 " + db.verify_test.countDocuments() + " 条记录")
    print("查询年龄 > 25 的用户:")
    db.verify_test.find({ age: { $gt: 25 } }).forEach(doc => print("  " + doc.name + " (" + doc.age + "岁, " + doc.city + ")"))
  ' || {
    error "测试数据插入失败。请确认 mongosh 能正常连接到 MongoDB。"
    return 1
  }

  return 0
}

main() {
  echo "============================================"
  echo "  MongoDB 一键安装与验证脚本"
  echo "  适用于 macOS / Linux / WSL"
  echo "  版本:MongoDB Community 7.0"
  echo "============================================"
  echo ""

  local NET
  NET=$(detect_network)

  local OS_TYPE
  if [[ "$(uname)" == "Darwin" ]]; then
    OS_TYPE="macos"
  else
    OS_TYPE="linux"
  fi

  check_root

  case "$OS_TYPE" in
    linux)
      install_linux "$NET"
      ;;
    macos)
      install_macos "$NET"
      ;;
  esac

  start_mongod
  verify_install

  if [ $? -eq 0 ]; then
    insert_test_data
  fi

  echo ""
  echo "============================================"
  info "全部完成!"
  echo ""
  echo "下一步:"
  echo "  进入交互式命令行:mongosh"
  echo "  查看状态:          sudo systemctl status mongod  (Linux)"
  echo "  停止服务:          sudo systemctl stop mongod    (Linux)"
  echo ""
  echo "想省本地部署精力?用云端 OpenAI 兼容 API(如 https://cloudzone-api.cyou/,90+ 模型、按量计费、国内直连)"
  echo "============================================"
}

main "$@"

Windows(PowerShell 版)

💡 说明:MongoDB 没有官方 Windows 原生守护进程的一键脚本。本脚本采用 WSL 引导方案——如果你的 Windows 装了 WSL,脚本会自动把 Linux 安装逻辑送入 WSL 内执行。如果没有 WSL,脚本会引导你安装并后续手动执行。

# ============================================================
#  MongoDB 一键安装与验证脚本(Windows PowerShell)
#  公开源码,欢迎审查 -- 不放心可先复制给 AI 判断
#  说明:通过 WSL 完成 MongoDB 安装(WSL = Windows Subsystem for Linux)
#  如果没有 WSL,脚本会引导你安装后再运行。
# ============================================================
$ErrorActionPreference = "Stop"

function Write-Info  { Write-Host "[INFO] $args" -ForegroundColor Green }
function Write-Warn  { Write-Host "[WARN] $args" -ForegroundColor Yellow }
function Write-Err   { Write-Host "[ERROR] $args" -ForegroundColor Red }
function Write-Step  { Write-Host "[STEP] $args" -ForegroundColor Cyan }

# ---------- 1. 检测网络环境 ----------
function Detect-Network {
    Write-Step "检测网络环境(国内 / 国外)..."
    try {
        $null = Invoke-WebRequest -Uri "https://github.com" -Method Head -TimeoutSec 5 -UseBasicParsing
        Write-Info "可直连 github.com,判定为海外网络"
        return "overseas"
    } catch {
        Write-Warn "无法直连 github.com,判定为国内网络环境"
        return "domestic"
    }
}

# ---------- 2. 检测 WSL ----------
Write-Step "检查 WSL 环境..."

if (-not (Get-Command wsl -ErrorAction SilentlyContinue)) {
    Write-Err "未找到 wsl 命令。Windows 10 需在 Microsoft Store 搜索 'WSL' 或 'Ubuntu' 安装。"
    Write-Host ""
    Write-Host "Windows 11 可直接以管理员 PowerShell 执行:wsl --install"
    Write-Host ""
    Write-Host "如果想直接在 Windows 上装 MongoDB(非 WSL):"
    Write-Host "  1. 去 https://www.mongodb.com/try/download/community 下载安装包"
    Write-Host "  2. 安装后以管理员运行 MongoDB Database Server"
    Write-Host "  3. 然后用 mongosh 连接即可"
    Write-Host ""
    Write-Host "是否继续使用 WSL 方式安装?[Y/N]"
    $choice = Read-Host
    if ($choice -ne "Y" -and $choice -ne "y") {
        Write-Info "已选择跳过。按上方指引手动安装。"
        exit 0
    }
    Write-Host "请按上述步骤安装 WSL/Ubuntu 后重新运行本脚本。"
    Write-Host "(或直接用 Windows 安装包,不走 WSL)"
    exit 0
}

Write-Info "WSL 已安装。正在检测 WSL 发行版..."
$wslDist = wsl -e sh -c 'cat /etc/os-release 2>/dev/null | grep PRETTY_NAME | cut -d"=" -f2 | tr -d "'"' 2>$null
if ([string]::IsNullOrWhiteSpace($wslDist)) { $wslDist = "Ubuntu" }
Write-Info "WSL 发行版$wslDist"

# ---------- 3. 把安装脚本注入 WSL 并执行 ----------
Write-Step "生成 WSL 内部安装脚本 ..."

$scriptContent = @'
#!/usr/bin/env bash
set -u
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m'; CYAN='\033[0;36m'; NC='\033[0m'
info()  { echo -e "${GREEN}[INFO]${NC} $1"; }
warn()  { echo -e "${YELLOW}[WARN]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1"; }
step()  { echo -e "${CYAN}[STEP]${NC} $1"; }

detect_network() {
  if curl -fsI --max-time 5 "https://claude.ai" >/dev/null 2>&1; then
    echo "overseas"
  else
    echo "domestic"
  fi
}

install_mongo() {
  local net="$1"
  step "在 WSL(${net}) 中安装 MongoDB Community 7.0 ..."

  sudo apt-get install -y gnupg curl >/dev/null 2>&1

  local key_url="https://www.mongodb.org/static/pgp/server-7.0.asc"
  if [ "$net" = "domestic" ]; then
    key_url="https://mirrors.aliyun.com/mongodb/static/pgp/server-7.0.asc"
  fi
  curl -fsSL --max-time 30 "$key_url" | sudo gpg --dearmor -o /usr/share/keyrings/mongodb-server-7.0.gpg 2>/dev/null

  local distro=$(. /etc/os-release && echo "$UBUNTU_CODENAME" 2>/dev/null || echo "jammy")
  local src="deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu ${distro}/mongodb-org/7.0 multiverse"
  if [ "$net" = "domestic" ]; then
    src="deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://mirrors.cloud.tencent.com/mongodb/apt/ubuntu ${distro}/mongodb-org/7.0 multiverse"
  fi
  echo "$src" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list >/dev/null

  sudo apt-get update -qq >/dev/null 2>&1
  if ! sudo apt-get install -y mongodb-org >/dev/null 2>&1; then
    error "MongoDB 安装失败请检查网络或手动下载 .deb 包安装"
    exit 1
  fi
  info "安装完成版本$(mongod --version | head -1)"
}

start_mongo() {
  step "启动 MongoDB 服务 ..."
  sudo mkdir -p /var/log/mongodb /var/lib/mongodb
  sudo mongod --fork --logpath /var/log/mongodb/mongod.log \
    --bind_ip 127.0.0.1 --port 27017 2>/dev/null || {
    info "mongod 似乎已在运行通过 systemd 或手动启动"
  }
}

verify() {
  step "验证连接 ... 最多等 15"
  for i in $(seq 1 15); do
    if mongosh --quiet --eval "db.runCommand('ping')" >/dev/null 2>&1; then
      info "MongoDB 连接成功"
      return 0
    fi
    sleep 1
  done
  error "连接超时请检查 mongod 是否正常运行"
  exit 1
}

insert_test() {
  step "插入 3 条测试数据 ..."
  mongosh --quiet --eval '
    use test
    db.verify_test.deleteMany({})
    db.verify_test.insertMany([
      { name: "Alice", age: 22, city: "Beijing" },
      { name: "Bob",   age: 28, city: "Shanghai" },
      { name: "Charlie", age: 35, city: "Shenzhen" }
    ])
    print("插入成功" + db.verify_test.countDocuments() + " 条记录")
    print("年龄 > 25 的用户")
    db.verify_test.find({ age: { $gt: 25 } }).forEach(d => print("  " + d.name + " (" + d.age + "岁, " + d.city + ")"))
  '
}

main() {
  echo "============================================"
  echo "  MongoDB 安装脚本WSL"
  echo "============================================"
  local net
  net=$(detect_network)
  install_mongo "$net"
  start_mongo
  verify
  insert_test
  echo ""
  echo "============================================"
  info "全部完成"
  echo "  进入 MongoDB 命令行mongosh"
  echo "============================================"
}

main "$@"
'@

$remoteScriptPath = "/tmp/install-mongodb-wsl.sh"
Write-Info "将脚本传入 WSL:$remoteScriptPath"
$scriptContent | wsl -e tee "$remoteScriptPath" >/dev/null 2>&1

if (-LASTEXITCODE -ne 0) {
    # 替代方案:用 wsl --share 管道
    $tempFile = Join-Path $env:TEMP "install-mongodb-wsl.sh"
    $scriptContent | Out-File -FilePath $tempFile -Encoding UTF8
    $tempWin = [System.IO.Path]::GetFullPath($tempFile)
    $mntPath = "/mnt/c" + $tempWin -replace '^C:', '' -replace '\\', '/'
    try {
        wsl -e cp "$mntPath" "$remoteScriptPath" 2>$null
    } catch {
        Write-Warn "传文件失败,改用 heredoc 方式注入..."
        wsl -e bash -c "$scriptContent" 2>&1
        exit $LASTEXITCODE
    }
}

Write-Host ""
Write-Host "============================================"
Write-Host "正在 WSL 中执行安装(首次安装可能需要 5-10 分钟)..."
Write-Host "============================================"
Write-Host ""

# 执行 WSL 内的安装脚本
wsl -e bash $remoteScriptPath
$exitCode = $LASTEXITCODE
Write-Host ""
Write-Host "============================================"

if ($exitCode -ne 0) {
    Write-Err "WSL 内安装失败(退出码 $exitCode)。"
    Write-Host "建议:"
    Write-Host "  1. 确认 WSL 发行版能联网:wsl -e curl https://claude.ai"
    Write-Host "  2. 手动在 WSL 中执行:curl -fsSL https://cleanresolver.com/scripts/install-mongodb-guide.sh | bash"
    Write-Host "  3. 或直接用 Windows 安装包:https://www.mongodb.com/try/download/community"
    exit 1
}

Write-Host ""
Write-Info "全部完成!接下来在 WSL 终端里:"
Write-Host "    mongosh          # 进入 MongoDB 命令行"
Write-Host "    use test"
Write-Host "    db.verify_test.find()"
Write-Host ""
Write-Host "Windows 浏览器可直接访问 http://localhost:27017(TCP 端口,非 HTTP)"
Write-Host "============================================"
Write-Host ""
Write-Host "小提示:不想本地搭环境?试试云端 AI API(https://cloudzone-api.cyou/,国内直连、90+ 模型按量计费)"

💡 不方便下载的同学可以直接复制上方完整源码,新建文本文档粘贴后改后缀为 .sh.ps1 运行。也可从以下链接下载:

  • Bash 版:https://cleanresolver.com/scripts/install-mongodb-guide.sh
  • PowerShell 版:https://cleanresolver.com/scripts/install-mongodb-guide.ps1

参考资源

  • 菜鸟教程 MongoDB 入门:https://www.runoob.com/mongodb/mongodb-tutorial.html
  • MongoDB 官方中文文档:https://docs.mongodb.com/manual/
  • MongoDB 社区版下载:https://www.mongodb.com/try/download/community
  • 国内镜像(腾讯云):https://mirrors.cloud.tencent.com/mongodb/