Appearance
MongoDB 入门
MongoDB 是一种流行的 NoSQL 数据库,它使用文档模型存储数据。本文将介绍 MongoDB 的核心概念和基本操作。
1. 基本概念
什么是 MongoDB
MongoDB 是一种开源的 NoSQL 数据库,它使用文档模型存储数据,而不是传统的表格结构。MongoDB 的文档是 JSON 格式的,这使得它非常灵活和易于使用。
核心概念
- 数据库 (Database):存储文档的容器
- 集合 (Collection):文档的集合,类似于关系型数据库的表格
- 文档 (Document):数据的基本单位,是 JSON 格式的对象
- 字段 (Field):文档中的键值对
- 索引 (Index):提高查询性能
- 聚合 (Aggregation):数据处理和分析
2. 安装与配置
安装 MongoDB
Windows
- 访问 MongoDB 官网
- 下载 MongoDB Community Server
- 运行安装程序,按照提示完成安装
- 启动 MongoDB 服务
macOS
- 使用 Homebrew 安装:
brew install mongodb-community - 启动 MongoDB 服务:
brew services start mongodb-community
Linux
- 按照 MongoDB 官网的说明安装
- 启动 MongoDB 服务:
sudo systemctl start mongod
配置 MongoDB
MongoDB 的配置文件通常位于:
- Windows:
C:\Program Files\MongoDB\Server\version\bin\mongod.cfg - macOS:
/usr/local/etc/mongod.conf - Linux:
/etc/mongod.conf
3. 基本操作
启动 MongoDB Shell
bash
mongo数据库操作
javascript
-- 显示所有数据库
show dbs
-- 切换到指定数据库(如果不存在则创建)
use mydb
-- 显示当前数据库
db
-- 删除当前数据库
db.dropDatabase()集合操作
javascript
-- 创建集合
db.createCollection('users')
-- 显示所有集合
show collections
-- 删除集合
db.users.drop()文档操作
插入文档
javascript
-- 插入单条文档
db.users.insertOne({
name: 'John Doe',
email: 'john@example.com',
age: 30,
address: {
street: '123 Main St',
city: 'New York',
state: 'NY'
},
hobbies: ['reading', 'swimming', 'hiking']
})
-- 插入多条文档
db.users.insertMany([
{
name: 'Jane Smith',
email: 'jane@example.com',
age: 25
},
{
name: 'Bob Johnson',
email: 'bob@example.com',
age: 35
}
])查询文档
javascript
-- 查询所有文档
db.users.find()
-- 查询指定条件的文档
db.users.find({ age: { $gt: 25 } })
-- 查询单个文档
db.users.findOne({ name: 'John Doe' })
-- 投影(只返回指定字段)
db.users.find({}, { name: 1, email: 1 })
-- 排序
db.users.find().sort({ age: 1 }) // 升序
db.users.find().sort({ age: -1 }) // 降序
-- 限制结果数量
db.users.find().limit(5)
-- 跳过结果
db.users.find().skip(5)更新文档
javascript
-- 更新单个文档
db.users.updateOne(
{ name: 'John Doe' },
{ $set: { age: 31 } }
)
-- 更新多个文档
db.users.updateMany(
{ age: { $gt: 30 } },
{ $set: { status: 'senior' } }
)
-- 替换文档
db.users.replaceOne(
{ name: 'John Doe' },
{
name: 'John Doe',
email: 'john.doe@example.com',
age: 31
}
)删除文档
javascript
-- 删除单个文档
db.users.deleteOne({ name: 'John Doe' })
-- 删除多个文档
db.users.deleteMany({ age: { $gt: 30 } })
-- 删除所有文档
db.users.deleteMany({})4. 查询操作符
比较操作符
- $eq:等于
- $ne:不等于
- $gt:大于
- $gte:大于等于
- $lt:小于
- $lte:小于等于
- $in:在指定数组中
- $nin:不在指定数组中
逻辑操作符
- $and:与
- $or:或
- $not:非
- $nor:既不...也不
元素操作符
- $exists:字段存在
- $type:字段类型
数组操作符
- $all:数组包含所有指定值
- $elemMatch:数组元素匹配指定条件
- $size:数组大小
其他操作符
- $regex:正则表达式
- $text:文本搜索
- $geoWithin:地理空间查询
5. 索引
创建索引
javascript
-- 创建单字段索引
db.users.createIndex({ name: 1 }) // 升序
db.users.createIndex({ name: -1 }) // 降序
-- 创建复合索引
db.users.createIndex({ name: 1, age: -1 })
-- 创建唯一索引
db.users.createIndex({ email: 1 }, { unique: true })
-- 创建文本索引
db.users.createIndex({ name: 'text', email: 'text' })
-- 创建地理空间索引
db.places.createIndex({ location: '2dsphere' })查看索引
javascript
-- 查看集合的索引
db.users.getIndexes()删除索引
javascript
-- 删除指定索引
db.users.dropIndex({ name: 1 })
-- 删除所有索引(除了 _id 索引)
db.users.dropIndexes()6. 聚合
聚合管道
javascript
-- 基本聚合
db.users.aggregate([
{ $match: { age: { $gt: 25 } } },
{ $group: { _id: '$age', count: { $sum: 1 } } },
{ $sort: { count: -1 } }
])
-- 其他聚合操作
-- $project:投影
-- $unwind:展开数组
-- $lookup:左连接
-- $limit:限制结果
-- $skip:跳过结果示例:计算每个年龄段的用户数量
javascript
db.users.aggregate([
{ $match: { age: { $exists: true } } },
{ $group: { _id: { $floor: { $divide: ['$age', 10] } }, count: { $sum: 1 } } },
{ $project: { age_group: { $concat: [{ $toString: { $multiply: ['$_id', 10] } }, '-', { $toString: { $add: [{ $multiply: ['$_id', 10] }, 9] } }], count: 1, _id: 0 } },
{ $sort: { age_group: 1 } }
])7. 复制集
复制集概念
复制集是一组 MongoDB 服务器,它们维护相同的数据副本。复制集提供了数据冗余和高可用性。
- 主节点 (Primary):处理所有写操作
- 从节点 (Secondary):复制主节点的数据,处理读操作
- 仲裁节点 (Arbiter):不存储数据,只参与选举
复制集配置
- 启动多个 MongoDB 实例
- 初始化复制集
- 添加成员到复制集
8. 分片
分片概念
分片是将数据分布到多个服务器的过程,它可以提高 MongoDB 的水平扩展性。
- 分片键:用于确定数据分布的字段
- 分片服务器:存储数据的服务器
- 路由服务器:处理客户端请求,将请求路由到正确的分片
- 配置服务器:存储分片集群的元数据
分片配置
- 启动配置服务器
- 启动路由服务器
- 启动分片服务器
- 启用分片
- 选择分片键
9. 与 Node.js 集成
安装 MongoDB 驱动
bash
npm install mongodb基本操作
javascript
const { MongoClient } = require('mongodb');
// 连接到 MongoDB
const uri = 'mongodb://localhost:27017';
const client = new MongoClient(uri);
async function main() {
try {
// 连接到数据库
await client.connect();
console.log('Connected to MongoDB');
// 选择数据库和集合
const db = client.db('mydb');
const users = db.collection('users');
// 插入文档
await users.insertOne({
name: 'John Doe',
email: 'john@example.com',
age: 30
});
// 查询文档
const result = await users.find({ age: { $gt: 25 } }).toArray();
console.log('Users older than 25:', result);
// 更新文档
await users.updateOne(
{ name: 'John Doe' },
{ $set: { age: 31 } }
);
// 删除文档
await users.deleteOne({ name: 'John Doe' });
} finally {
// 关闭连接
await client.close();
}
}
main().catch(console.error);10. 最佳实践
数据模型设计
- 文档结构:设计合理的文档结构,避免过度嵌套
- 分片键选择:选择高基数、均匀分布的分片键
- 索引设计:创建适当的索引,提高查询性能
- 数据备份:定期备份数据,防止数据丢失
查询优化
- 使用索引:确保查询条件上有索引
- 限制结果:使用 limit() 限制返回的行数
- 投影:只返回需要的字段
- 避免全集合扫描:使用索引减少扫描范围
性能优化
- 批量操作:使用批量操作减少网络开销
- 连接池:使用连接池管理数据库连接
- 监控:监控 MongoDB 的性能和健康状况
- 调整配置:根据服务器资源调整 MongoDB 配置
11. 常见问题与解决方案
连接问题
问题:无法连接到 MongoDB 解决方案:
- 检查 MongoDB 服务是否运行
- 检查连接字符串是否正确
- 检查网络连接是否正常
性能问题
问题:查询速度慢 解决方案:
- 创建适当的索引
- 优化查询语句
- 考虑分片
数据丢失
问题:数据丢失 解决方案:
- 启用复制集
- 定期备份数据
- 使用 writeConcern 确保数据写入
内存使用过高
问题:MongoDB 内存使用过高 解决方案:
- 调整 WiredTiger 缓存大小
- 优化查询,减少内存使用
- 考虑分片
12. 工具推荐
管理工具
- MongoDB Compass:官方 GUI 工具
- Robo 3T:开源 GUI 工具
- Studio 3T:商业 GUI 工具
监控工具
- MongoDB Atlas:云服务,提供监控功能
- MongoDB Ops Manager:企业级监控工具
- Prometheus + Grafana:开源监控方案
备份工具
- mongodump:官方备份工具
- MongoDB Atlas Backup:云备份服务
13. 总结
MongoDB 是一种强大的 NoSQL 数据库,它使用文档模型存储数据,具有灵活性高、扩展性强等优点。通过学习 MongoDB 的基本概念和操作,我们可以有效地使用 MongoDB 存储和管理数据。
MongoDB 的核心特性包括:
- 文档模型
- 灵活的查询
- 强大的索引
- 聚合框架
- 复制集和分片
通过合理的设计和优化,MongoDB 可以为各种应用场景提供高性能、可靠的数据存储服务。