Skip to main content

MongoDB

MongoDB 是一个流行的 NoSQL 数据库,它使用 JSON 格式文档存储数据,非常适合处理大量的非结构化数据。

特点

  • 文档型数据库
  • 灵活的数据模型
  • 高性能
  • 易于扩展
  • 支持复杂查询

安装

macOS (使用 Homebrew)

brew tap mongodb/brew
brew install mongodb-community
brew services start mongodb-community

基本概念

  • 数据库(Database): 包含集合的容器
  • 集合(Collection): 类似于关系数据库中的表
  • 文档(Document): 类似于关系数据库中的行,使用 BSON(二进制 JSON)格式
  • 字段(Field): 文档中的键值对

基本操作

1. 数据库操作

// 显示所有数据库
show dbs

// 使用/创建数据库
use myapp

// 删除当前数据库
db.dropDatabase()

2. 集合操作

// 创建集合
db.createCollection("users")

// 显示所有集合
show collections

// 删除集合
db.users.drop()

3. 文档操作

// 插入单个文档
db.users.insertOne({
username: "john_doe",
email: "john@example.com",
profile: {
age: 30,
city: "New York"
},
created_at: new Date()
})

// 批量插入文档
db.users.insertMany([
{
username: "jane_doe",
email: "jane@example.com",
profile: { age: 25, city: "London" }
},
{
username: "bob_smith",
email: "bob@example.com",
profile: { age: 35, city: "Paris" }
}
])

// 查询文档
db.users.find({ "profile.city": "New York" })

// 更新文档
db.users.updateOne(
{ username: "john_doe" },
{
$set: { "profile.verified": true },
$currentDate: { last_modified: true }
}
)

// 删除文档
db.users.deleteOne({ username: "john_doe" })

高级查询

1. 查询操作符

// 比较操作符
db.users.find({
"profile.age": { $gt: 25, $lt: 35 }
})

// 逻辑操作符
db.users.find({
$or: [
{ "profile.city": "New York" },
{ "profile.city": "London" }
]
})

// 正则表达式
db.users.find({
email: /.*@example\.com$/
})

2. 聚合操作

// 使用聚合管道
db.orders.aggregate([
// 匹配阶段
{
$match: {
status: "completed"
}
},
// 分组阶段
{
$group: {
_id: "$customer_id",
total_spent: { $sum: "$amount" },
order_count: { $sum: 1 }
}
},
// 排序阶段
{
$sort: {
total_spent: -1
}
}
])

// 查找并修改
db.users.findAndModify({
query: { username: "john_doe" },
update: { $inc: { login_count: 1 } },
new: true
})

Node.js 示例

const { MongoClient } = require('mongodb');

const uri = 'mongodb://localhost:27017';
const client = new MongoClient(uri);

// 连接数据库
async function connect() {
try {
await client.connect();
console.log('Connected to MongoDB');
return client.db('myapp');
} catch (err) {
console.error('Connection error:', err);
throw err;
}
}

// CRUD 操作示例
async function userOperations() {
const db = await connect();
const users = db.collection('users');

try {
// 创建
const insertResult = await users.insertOne({
username: 'john_doe',
email: 'john@example.com',
created_at: new Date()
});
console.log('Inserted ID:', insertResult.insertedId);

// 读取
const user = await users.findOne({ username: 'john_doe' });
console.log('Found user:', user);

// 更新
const updateResult = await users.updateOne(
{ username: 'john_doe' },
{
$set: { last_login: new Date() },
$inc: { login_count: 1 }
}
);
console.log('Updated count:', updateResult.modifiedCount);

// 删除
const deleteResult = await users.deleteOne({ username: 'john_doe' });
console.log('Deleted count:', deleteResult.deletedCount);

} catch (err) {
console.error('Operation error:', err);
} finally {
await client.close();
}
}

// 事务示例
async function transactionExample() {
const session = client.startSession();
try {
await session.withTransaction(async () => {
const db = client.db('myapp');

// 转账操作
await db.collection('accounts').updateOne(
{ user_id: 'user1' },
{ $inc: { balance: -100 } },
{ session }
);

await db.collection('accounts').updateOne(
{ user_id: 'user2' },
{ $inc: { balance: 100 } },
{ session }
);
});
} finally {
await session.endSession();
}
}

索引

// 创建单字段索引
db.users.createIndex({ email: 1 })

// 创建复合索引
db.users.createIndex({
username: 1,
email: 1
})

// 创建文本索引
db.articles.createIndex({
title: "text",
content: "text"
})

// 创建地理空间索引
db.places.createIndex({
location: "2dsphere"
})

// 查看索引
db.users.getIndexes()

性能优化

1. 查询优化

// 使用 explain() 分析查询
db.users.find({
username: "john_doe"
}).explain("executionStats")

// 使用投影限制返回字段
db.users.find(
{ status: "active" },
{ username: 1, email: 1 }
)

// 使用 limit 和 skip 进行分页
db.users.find()
.sort({ created_at: -1 })
.skip(20)
.limit(10)

2. 数据模型优化

// 嵌入式文档(适用于一对一关系)
{
username: "john_doe",
profile: {
address: {
street: "123 Main St",
city: "New York",
country: "USA"
}
}
}

// 引用式文档(适用于一对多关系)
{
_id: ObjectId("..."),
username: "john_doe",
posts: [ObjectId("..."), ObjectId("...")]
}

备份和恢复

# 备份数据库
mongodump --db=myapp --out=/backup/

# 恢复数据库
mongorestore --db=myapp /backup/myapp/

# 导出集合为 JSON
mongoexport --db=myapp --collection=users --out=users.json

# 导入 JSON 数据
mongoimport --db=myapp --collection=users --file=users.json

监控和维护

// 查看数据库状态
db.stats()

// 查看集合状态
db.users.stats()

// 修复数据库
db.repairDatabase()

// 压缩集合
db.runCommand({ compact: "users" })

安全性

// 创建用户
db.createUser({
user: "appuser",
pwd: "password",
roles: [
{ role: "readWrite", db: "myapp" }
]
})

// 启用身份验证
// 在 mongod.conf 中添加:
// security:
// authorization: enabled

// 使用身份验证连接
mongo -u appuser -p password --authenticationDatabase myapp