MongoDB NoSQL 数据库
MongoDB 是最流行的 NoSQL 文档数据库,用类似 JSON 的格式存储数据(叫 BSON),不需要预定义表结构,特别适合快速开发和处理非结构化数据,是生信项目中存储样本元数据、分析结果的好选择。
核心知识点
| 知识点 | 说明 |
|---|
| 数据库类型 | 文档型 NoSQL 数据库 |
| 最新版本 | v8.2(性能大幅提升,支持向量搜索) |
| 数据格式 | BSON(Binary JSON),类似 JSON 的二进制格式 |
| 核心优势 | 灵活 schema、水平扩展、丰富查询、ACID 事务 |
| 适用场景 | Web 应用、物联网、日志存储、生信元数据管理 |
| v8.0 亮点 | 吞吐量提升 25%、批量插入快 54%、向量搜索 |
| 许可证 | SSPL(Server Side Public License) |
| 云服务 | MongoDB Atlas(全托管云数据库) |
安装配置
方法一:Docker 安装(推荐,最简单)
# 用 Docker 运行 MongoDB
docker run -d \
--name mongodb \ # 容器名
-p 27017:27017 \ # 端口映射
-v mongodb_data:/data/db \ # 数据持久化
-e MONGO_INITDB_ROOT_USERNAME=admin \ # 管理员用户名
-e MONGO_INITDB_ROOT_PASSWORD=password \ # 管理员密码
mongo:8 # 使用 MongoDB 8 镜像
# 验证运行
docker exec -it mongodb mongosh # 进入 MongoDB Shell
方法二:系统安装(Ubuntu/Debian)
# 导入 MongoDB GPG 密钥
curl -fsSL https://www.mongodb.org/static/pgp/server-8.0.asc | \
sudo gpg -o /usr/share/keyrings/mongodb-server-8.0.gpg --dearmor
# 添加仓库
echo "deb [ signed-by=/usr/share/keyrings/mongodb-server-8.0.gpg ] \
https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/8.0 multiverse" | \
sudo tee /etc/apt/sources.list.d/mongodb-org-8.0.list
# 安装
sudo apt update && sudo apt install -y mongodb-org # 安装 MongoDB
# 启动服务
sudo systemctl start mongod # 启动
sudo systemctl enable mongod # 设置开机自启
mongosh # 连接 MongoDB Shell
方法三:Conda 安装(轻量级)
conda install -c conda-forge mongodb # 安装 MongoDB
mongod --dbpath ./data/db # 指定数据目录启动
基本使用
1. 数据库和集合操作
// 在 mongosh 中操作
// 查看所有数据库
show dbs // 列出所有数据库
// 创建/切换数据库
use bioinfo_db // 切换到 bioinfo_db(不存在则创建)
// 创建集合(类似 SQL 的表)
db.createCollection("samples") // 创建 samples 集合
// 查看当前数据库的集合
show collections // 列出所有集合
2. 插入文档
// 插入单个文档
db.samples.insertOne({
sample_id: "T2D_001", // 样本 ID
patient_age: 55, // 患者年龄
diagnosis: "T2D", // 诊断
sequencing: { // 嵌套文档(测序信息)
platform: "Illumina NovaSeq",
read_length: 150,
total_reads: 50000000
},
taxa: ["Bacteroides", "Firmicutes", "Proteobacteria"], // 数组
created_at: new Date() // 时间戳
})
// 批量插入
db.samples.insertMany([
{ sample_id: "T2D_002", diagnosis: "T2D", bmi: 28.5 },
{ sample_id: "HC_001", diagnosis: "Healthy", bmi: 22.0 },
{ sample_id: "HC_002", diagnosis: "Healthy", bmi: 21.5 }
])
3. 查询文档
// 查询所有文档
db.samples.find() // 返回所有文档
// 条件查询
db.samples.find({ diagnosis: "T2D" }) // 查找所有 T2D 样本
// 比较查询
db.samples.find({ bmi: { $gt: 25 } }) // BMI > 25 的样本
db.samples.find({ bmi: { $gte: 20, $lte: 30 } }) // BMI 在 20-30 之间
// 数组查询
db.samples.find({ taxa: "Bacteroides" }) // 包含 Bacteroides 的样本
// 嵌套文档查询
db.samples.find({ "sequencing.platform": "Illumina NovaSeq" })
// 限制返回字段(投影)
db.samples.find(
{ diagnosis: "T2D" }, // 查询条件
{ sample_id: 1, bmi: 1, _id: 0 } // 只返回 sample_id 和 bmi
)
// 排序和限制
db.samples.find().sort({ bmi: -1 }).limit(5) // BMI 降序排列,取前 5
4. 更新文档
// 更新单个文档
db.samples.updateOne(
{ sample_id: "T2D_001" }, // 查询条件
{ $set: { bmi: 29.0 } } // 设置新值
)
// 更新多个文档
db.samples.updateMany(
{ diagnosis: "T2D" }, // 匹配所有 T2D
{ $set: { group: "case" } } // 添加 group 字段
)
// 数组操作
db.samples.updateOne(
{ sample_id: "T2D_001" },
{ $push: { taxa: "Lactobacillus" } } // 向数组添加元素
)
5. 删除文档
// 删除单个文档
db.samples.deleteOne({ sample_id: "T2D_002" })
// 删除多个文档
db.samples.deleteMany({ diagnosis: "Healthy" }) // 删除所有健康样本
// 删除集合
db.samples.drop() // 删除整个集合
高级用法
1. 聚合管道(Aggregation Pipeline)
// 按诊断分组统计
db.samples.aggregate([
{ $group: { // 分组
_id: "$diagnosis", // 按 diagnosis 分组
count: { $sum: 1 }, // 计数
avg_bmi: { $avg: "$bmi" }, // 平均 BMI
max_bmi: { $max: "$bmi" } // 最大 BMI
}},
{ $sort: { count: -1 } } // 按计数降序
])
// 多阶段聚合
db.samples.aggregate([
{ $match: { diagnosis: "T2D" } }, // 过滤 T2D 样本
{ $unwind: "$taxa" }, // 展开 taxa 数组
{ $group: { // 按物种分组计数
_id: "$taxa",
count: { $sum: 1 }
}},
{ $sort: { count: -1 } }, // 降序排列
{ $limit: 10 } // 取前 10
])
2. 索引优化
// 创建索引(加速查询)
db.samples.createIndex({ sample_id: 1 }) // 单字段索引
db.samples.createIndex({ diagnosis: 1, bmi: -1 }) // 复合索引
db.samples.createIndex({ sample_id: 1 }, { unique: true }) // 唯一索引
// 查看索引
db.samples.getIndexes() // 列出所有索引
// 查询性能分析
db.samples.find({ diagnosis: "T2D" }).explain("executionStats")
3. Python 操作(pymongo)
from pymongo import MongoClient # 导入 MongoDB Python 驱动
# 连接 MongoDB
client = MongoClient("mongodb://admin:password@localhost:27017/") # 连接
# 选择数据库和集合
db = client["bioinfo_db"] # 选择数据库
samples = db["samples"] # 选择集合
# 插入
result = samples.insert_one({ # 插入一个文档
"sample_id": "T2D_003",
"diagnosis": "T2D",
"abundance": {"Bacteroides": 0.35, "Firmicutes": 0.40}
})
print(f"插入 ID: {result.inserted_id}")
# 查询
for doc in samples.find({"diagnosis": "T2D"}): # 查询所有 T2D
print(doc["sample_id"], doc.get("bmi"))
# 聚合
pipeline = [
{"$group": {"_id": "$diagnosis", "count": {"$sum": 1}}}
]
for result in samples.aggregate(pipeline): # 聚合查询
print(result)
# 关闭连接
client.close()
常见报错与解决
| 报错信息 | 原因 | 解决方法 |
|---|
connection refused | MongoDB 服务未启动 | sudo systemctl start mongod |
Authentication failed | 用户名或密码错误 | 检查连接字符串中的用户名密码 |
E11000 duplicate key error | 插入了重复的唯一键 | 检查唯一索引字段是否重复 |
ns not found | 集合不存在 | 检查集合名拼写 |
| 磁盘空间不足 | 数据文件太大 | 清理数据或扩展磁盘,检查 journal 日志 |
BSON field too large | 单个文档超过 16MB 限制 | 拆分大文档或使用 GridFS 存储大文件 |
速查表
// ===== MongoDB 速查表 =====
// === 数据库操作 ===
show dbs // 列出数据库
use mydb // 切换数据库
db.dropDatabase() // 删除当前数据库
// === 集合操作 ===
show collections // 列出集合
db.createCollection("name") // 创建集合
db.name.drop() // 删除集合
// === CRUD 操作 ===
db.col.insertOne({...}) // 插入一条
db.col.insertMany([{...}, {...}]) // 插入多条
db.col.find({key: "value"}) // 查询
db.col.find().sort({key: 1}) // 排序(1升序 -1降序)
db.col.find().limit(10) // 限制数量
db.col.updateOne({条件}, {$set: {更新}}) // 更新
db.col.deleteOne({条件}) // 删除
// === 查询操作符 ===
// $gt $gte $lt $lte $ne 比较
// $in $nin 包含/不包含
// $and $or $not 逻辑
// $exists 字段存在
// $regex 正则匹配
// === 聚合 ===
// $match 过滤
// $group 分组
// $sort 排序
// $limit 限制
// $project 投影
// $unwind 展开数组
// $lookup 关联查询(类似 JOIN)
// === 索引 ===
db.col.createIndex({key: 1}) // 创建索引
db.col.getIndexes() // 查看索引
db.col.dropIndex("index_name") // 删除索引
// === Python (pymongo) ===
// pip install pymongo
// client = MongoClient("mongodb://localhost:27017/")
// db = client["mydb"]
// col = db["mycol"]
// col.insert_one({...})
// col.find({...})