MongoDB 作为 NoSQL 数据库,采用文档存储而非关系型表格结构,但其核心操作与 SQL 有诸多相似之处。本文将详细介绍 MongoDB 的各类操作,特别是强大的聚合功能。这里跟上一篇一样,使用命令行进行操作,也需要单独下载mongosh工具,或者使用可视化客户端连接。
1. 数据库与集合操作
1.1 数据库管理
// 创建或切换数据库(MongoDB 按需创建)
use mydb # 相当于SQL中的 CREATE DATABASE mydb 和 USE mydb;;
// 查看当前数据库
db.getName() # 相当于SQL中的 select database();
// 删除当前数据库
db.dropDatabase() # 相当于SQL中的 DROP DATABASE mydb;
// 查看所有数据库
show dbs # 相当于SQL中的 SHOW DATABASES;
1.2 集合管理
// 创建集合(MongoDB 按需创建)
db.createCollection("users") # 相当于SQL中的 CREATE TABLE users(id INT, name VARCHAR(50) ...)
// 创建带选项的集合(如固定大小)
db.createCollection("logs", { capped: true, size: 10485760 }) # size单位字节,10485760为10MB,其它高级用法如验证文档格式可通过 db.createCollection.help() 获取文档地址查看
// 查看所有集合
show collections # 相当于SQL中的 SHOW TABLES;
// 删除集合
db.users.drop() # 相当于SQL中的 DROP TABLE users;
2. 文档操作(增删改查)
2.1 插入文档
// 插入单条文档,相当于SQL中的:INSERT INTO users (id, name, age) VALUES (1, 'Alice', 30);
db.users.insertOne({
_id: 1,
name: "Alice",
age: 30,
hobbies: ["reading", "swimming"]
})
// 插入多条文档,相当于SQL中的:INSERT INTO users (id, name, age) VALUES (2, 'Bob', 25), (3, 'Charlie', 35);
db.users.insertMany([
{ _id: 2, name: "Bob", age: 25 },
{ _id: 3, name: "Charlie", age: 35 }
])
2.2 查询文档
// 查询所有文档,相当于SQL的:SELECT * FROM users;
db.users.find()
// 条件查询(等于),相当于SQL的:SELECT * FROM users WHERE name = 'Alice';
db.users.find({ name: "Alice" })
// 条件查询(大于),相当于SQL的:SELECT * FROM users WHERE age > 30;
db.users.find({ age: { $gt: 30 } })
// 逻辑查询(AND),相当于SQL的:SELECT * FROM users WHERE age > 25 AND name != 'Charlie';
db.users.find({ age: { $gt: 25 }, name: { $ne: "Charlie" } })
// 逻辑查询(OR),相当于SQL的:SELECT * FROM users WHERE age < 30 OR name = 'Alice';
db.users.find({ $or: [{ age: { $lt: 30 } }, { name: "Alice" }] })
// 投影(仅返回指定字段),相当于SQL的:SELECT name, age FROM users WHERE name = 'Alice';
db.users.find({ name: "Alice" }, { name: 1, age: 1, _id: 0 })
2.3 更新文档
// 更新单条文档,相当于SQL的:UPDATE users SET age = 31 WHERE name = 'Alice';
db.users.updateOne(
{ name: "Alice" },
{ $set: { age: 31 }, $addToSet: { hobbies: "running" } }
)
// 更新多条文档,相当于SQL的:UPDATE users SET age = age + 1 WHERE age >= 30;
db.users.updateMany(
{ age: { $gte: 30 } },
{ $inc: { age: 1 } }
)
// 替换文档,相当于SQL的: REPLACE INTO users (id, name, age, job) VALUES (2, 'Robert', 26, 'Engineer');
db.users.replaceOne(
{ name: "Bob" },
{ name: "Robert", age: 26, job: "Engineer" }
)
2.4 删除文档
// 删除单条文档,相当于SQL的:DELETE FROM users WHERE name = 'Charlie';
db.users.deleteOne({ name: "Charlie" })
// 删除多条文档,相当于SQL的:DELETE FROM users WHERE age < 30;
db.users.deleteMany({ age: { $lt: 30 } })
// 删除所有文档(保留集合),相当于SQL的:DELETE FROM users;
db.users.deleteMany({})
3. 索引操作
3.1 创建索引
// 创建单字段索引
db.users.createIndex({ name: 1 }) // 1 表示升序,-1 表示降序
// 创建复合索引
db.users.createIndex({ age: 1, name: -1 })
// 创建唯一索引
db.users.createIndex({ email: 1 }, { unique: true })
// 创建文本索引(用于全文搜索)
db.users.createIndex({ bio: "text" })
3.2 查看和删除索引
// 查看集合所有索引
db.users.getIndexes()
// 删除索引
db.users.dropIndex("name_1") // 索引名格式:字段名_排序方向
4. 聚合框架
MongoDB 聚合框架通过管道(pipeline)操作实现复杂的数据处理,功能远超 SQL 的 GROUP BY
。
4.1 常用聚合操作符
$match
:筛选文档,类似 SQL 的WHERE
$group
:分组,类似 SQL 的GROUP BY
$project
:投影,类似 SQL 的SELECT
$sort
:排序,类似 SQL 的ORDER BY
$limit
:限制结果数量,类似 SQL 的LIMIT
$skip
:跳过文档,类似 SQL 的OFFSET
$lookup
:关联查询,类似 SQL 的JOIN
4.2 聚合示例
示例 1:统计各年龄段人数
# 相当于SQL的:SELECT age, COUNT(*) as count FROM users GROUP BY age ORDER BY count DESC;
db.users.aggregate([
{ $group: { _id: "$age", count: { $sum: 1 } } },
{ $sort: { count: -1 } }
])
示例 2:计算平均年龄
# 相当于SQL的:SELECT AVG(age) as averageAge FROM users;
db.users.aggregate([
{ $group: { _id: null, averageAge: { $avg: "$age" } } }
])
示例 3:多表关联查询
# 假设有 orders 集合,结构:{ userId: 1, amount: 100 }
# 相当于SQL:
# SELECT u.name as userName, o.amount
# FROM orders o
# JOIN users u
# ON o.userId = u.id;
db.orders.aggregate([
{
$lookup: {
from: "users",
localField: "userId",
foreignField: "_id",
as: "userInfo"
}
},
{ $unwind: "$userInfo" }, // 展开数组
{ $project: { _id: 0, userName: "$userInfo.name", amount: 1 } }
])
示例 4:复杂聚合(统计每个用户的订单总数和总金额)
# 相当于SQL:
# SELECT
# u.name as userName,
# COUNT(o.id) as totalOrders,
# SUM(o.amount) as totalAmount
# FROM orders o
# JOIN users u ON o.userId = u.id
# GROUP BY u.id, u.name
# ORDER BY totalAmount DESC;
db.orders.aggregate([
{ $group: {
_id: "$userId",
totalOrders: { $sum: 1 },
totalAmount: { $sum: "$amount" }
}},
{ $lookup: {
from: "users",
localField: "_id",
foreignField: "_id",
as: "user"
}},
{ $unwind: "$user" },
{ $project: {
_id: 0,
userName: "$user.name",
totalOrders: 1,
totalAmount: 1
}},
{ $sort: { totalAmount: -1 } }
])
5. 高级聚合操作
5.1 数组操作
// 假设有 products 集合:{ name: "phone", tags: ["electronics", "mobile"] }
db.products.aggregate([
{ $unwind: "$tags" }, // 展开数组
{ $group: { _id: "$tags", count: { $sum: 1 } } }, // 统计标签出现次数
{ $sort: { count: -1 } }
])
5.2 窗口函数(MongoDB 5.0+)
// 计算每个用户的订单金额排名
db.orders.aggregate([
{ $sort: { amount: -1 } },
{
$setWindowFields: {
partitionBy: null,
sortBy: { amount: -1 },
output: { rank: { $rank: {} } }
}
}
])
5.3 地理空间聚合
// 假设有 stores 集合:{ name: "Store A", location: { type: "Point", coordinates: [longitude, latitude] } }
db.stores.aggregate([
{
$geoNear: {
near: { type: "Point", coordinates: [114.06667, 22.61667] }, // 深圳市中心
distanceField: "distance",
maxDistance: 10000, // 单位米,即10公里内
spherical: true
}
},
{ $limit: 5 } // 返回最近的5个商店
])
6. 执行计划与优化
6.1 查看聚合执行计划
db.users.explain("executionStats").aggregate([
{ $match: { age: { $gt: 25 } } },
{ $group: { _id: "$city", avgAge: { $avg: "$age" } } }
])
6.2 优化建议
尽早过滤数据:在管道开头使用
$match
减少数据量合理使用索引:为
$match
和$sort
字段创建索引避免大数据集排序:
$sort
操作会将数据加载到内存,可能导致内存溢出使用
$indexStats
分析索引使用情况:db.users.aggregate([{ $indexStats: {} }])
7. 帮助命令
7.1 数据库级帮助
db.help() // 显示数据库操作命令列表
db.stats() // 查看当前数据库统计信息(含存储细节)
7.2 集合级帮助
db.collection.help() // 列出指定集合支持的操作方法
db.collection.stats() // 查看集合存储统计
db.collection.getIndexes() // 查看集合索引配置
7.3 方法级帮助
db.createCollection.help() // 查看创建集合方法的参数说明
db.collection.insert.help() // 查看插入操作的语法规范
总结
MongoDB 的操作虽然语法与 SQL 不同,但核心功能高度相似。聚合框架提供了比 SQL 更强大、灵活的数据处理能力,尤其适合复杂数据分析场景。掌握 MongoDB 的操作和聚合框架,能让你更高效地管理和分析非结构化数据。