MongoDB基础知识
MongoDB基础知识
目录
- 基础篇
- 一、MongoDB入门指南(零基础必读)
- 二、MongoDB简介
- 三、MongoDB安装与配置
- 四、MongoDB基本操作
- 五、MongoDB查询操作
- 进阶篇
- 六、MongoDB索引
- 七、MongoDB聚合操作
- 八、MongoDB数据模型
- 九、MongoDB安全
- 十、MongoDB备份恢复
- 十一、MongoDB性能优化
- 十二、MongoDB高级特性
- 十三、MongoDB复制集
- 十四、MongoDB分片集群
- 应用篇
- 十五、MongoDB性能诊断
- 十六、MongoDB数据迁移
- 十七、MongoDB应用开发最佳实践
- 十八、MongoDB运维管理
- 十九、MongoDB常见应用场景示例
- 二十、MongoDB与Java集成
- 二十一、MongoDB与Spring Boot集成
- 二十二、MongoDB与Docker部署
- 最佳实践篇
- 二十三、MongoDB常见问题解答
- 二十四、MongoDB最佳实践总结
基础篇
一、MongoDB入门指南(零基础必读)
1.1 MongoDB是什么?
把MongoDB想象成一个超级大的Excel表格本:
- 数据库(Database)就像一个Excel工作簿
- 集合(Collection)就像工作簿中的工作表
- 文档(Document)就像工作表中的一行数据
- 字段(Field)就像表格中的列
与传统MySQL数据库相比:
- MySQL要求表格结构固定(每列的类型必须一致)
- MongoDB更灵活,同一个集合中的文档可以有不同的字段
1.2 为什么选择MongoDB?
-
容易上手
- 数据格式类似JSON,对开发者友好
- 不需要设计复杂的表关系
- 存储格式灵活,想存什么就存什么
-
适合的应用场景
- 存储网站用户数据
- 存储商品评论信息
- 记录系统日志
- 存储游戏数据
1.3 基础操作入门示例
1. 数据库操作
// 创建/切换到"我的数据库"
use mydb// 查看有哪些数据库
show dbs// 删除当前使用的数据库
db.dropDatabase()
2. 集合操作
// 创建"用户信息"集合
db.createCollection("用户信息")// 查看所有集合
show collections// 删除"用户信息"集合
db.用户信息.drop()
3. 实用操作示例
添加用户信息
// 添加一个用户
db.用户信息.insertOne({姓名: "小明",年龄: 18,爱好: ["打游戏", "看电影"],联系方式: {手机: "13812345678",邮箱: "xiaoming@example.com"}
})
查询用户信息
// 查找所有用户
db.用户信息.find()// 查找叫"小明"的用户
db.用户信息.find({姓名: "小明"})// 查找18岁的用户
db.用户信息.find({年龄: 18})// 查找大于18岁的用户
db.用户信息.find({年龄: {$gt: 18}})
1.4 新手常见问题解决
1. 数据重复问题
// 设置用户名不能重复
db.users.createIndex({用户名: 1}, {unique: true})// 检查用户名是否存在
const userExists = db.users.findOne({用户名: "xiaoming"})
if (!userExists) {// 可以注册
}
2. 查询速度慢问题
// 为常用查询字段创建索引
db.users.createIndex({年龄: 1})
db.users.createIndex({注册时间: 1})// 只返回需要的字段
db.users.find({年龄: {$gt: 18}},{用户名: 1, 年龄: 1, _id: 0}
)
1.5 新手使用建议
-
命名建议
- 数据库名用小写字母
- 集合名用有意义的名字(如users、products)
- 字段名用简单易懂的名字
-
数据组织建议
- 相关的数据尽量放在一起
- 避免过深的数据嵌套
- 数组中不要存太多数据
-
查询建议
- 常用查询字段要加索引
- 查询时只获取需要的字段
- 避免一次查询太多数据
-
实用技巧
- 使用复合查询减少查询次数
- 使用批量操作提高效率
- 定期备份重要数据
二、MongoDB简介
2.1 什么是MongoDB?
MongoDB是一个开源的文档型数据库,具有以下特点:
- 高性能、高可用性、易扩展
- 支持动态查询
- 支持索引
- 支持复制和分片
- 支持多种编程语言
2.2 基本概念
-
数据库(Database)
- MongoDB中的数据库是一个集合的容器
- 每个数据库都有独立的权限控制
-
集合(Collection)
- 类似于关系型数据库中的表
- 不需要预先定义结构
- 可以包含不同结构的文档
-
文档(Document)
- 类似于关系型数据库中的行
- 使用BSON格式(JSON的二进制形式)
- 可以包含不同类型的字段
-
字段(Field)
- 文档中的键值对
- 支持多种数据类型
- 可以嵌套和数组
三、MongoDB安装与配置
3.1 安装MongoDB
# Windows安装
# 1. 下载MongoDB安装包
# 2. 运行安装程序
# 3. 配置环境变量# Linux安装
sudo apt-get update
sudo apt-get install -y mongodb# Mac安装
brew tap mongodb/brew
brew install mongodb-community
3.2 启动MongoDB
# Windows启动
net start MongoDB# Linux启动
sudo systemctl start mongodb# Mac启动
brew services start mongodb-community
3.3 连接MongoDB
# 命令行连接
mongosh# 指定主机和端口连接
mongosh --host localhost --port 27017# 使用用户名密码连接
mongosh --username admin --password password
四、MongoDB基本操作
4.1 数据库操作
// 创建/切换数据库
use mydb// 查看所有数据库
show dbs// 删除当前数据库
db.dropDatabase()// 查看当前数据库
db
4.2 集合操作
// 创建集合
db.createCollection("users")// 查看所有集合
show collections// 删除集合
db.users.drop()// 查看集合统计信息
db.users.stats()
4.3 文档操作
// 插入单个文档
db.users.insertOne({name: "张三",age: 25,email: "zhangsan@example.com",hobbies: ["读书", "运动"],address: {city: "北京",street: "朝阳区"}
})// 插入多个文档
db.users.insertMany([{name: "李四",age: 30,email: "lisi@example.com"},{name: "王五",age: 28,email: "wangwu@example.com"}
])// 查询文档
db.users.find()// 条件查询
db.users.find({ age: { $gt: 25 } })// 更新文档
db.users.updateOne({ name: "张三" },{ $set: { age: 26 } }
)// 删除文档
db.users.deleteOne({ name: "张三" })
五、MongoDB查询操作
5.1 基础查询
// 查询所有文档
db.users.find()// 条件查询
db.users.find({ age: 25 })// 比较操作符
db.users.find({ age: { $gt: 25 } }) // 大于
db.users.find({ age: { $lt: 25 } }) // 小于
db.users.find({ age: { $gte: 25 } }) // 大于等于
db.users.find({ age: { $lte: 25 } }) // 小于等于
db.users.find({ age: { $ne: 25 } }) // 不等于// 逻辑操作符
db.users.find({ $or: [{ age: 25 }, { age: 30 }] }) // OR
db.users.find({ $and: [{ age: 25 }, { name: "张三" }] }) // AND
db.users.find({ age: { $not: { $gt: 25 } } }) // NOT// 限制返回字段
db.users.find({}, { name: 1, age: 1, _id: 0 })// 排序
db.users.find().sort({ age: 1 }) // 升序
db.users.find().sort({ age: -1 }) // 降序// 分页
db.users.find().skip(10).limit(5)
5.2 高级查询
// 正则表达式查询
db.users.find({ name: /^张/ })// 数组查询
db.users.find({ hobbies: "读书" })
db.users.find({ hobbies: { $all: ["读书", "运动"] } })
db.users.find({ hobbies: { $size: 2 } })// 嵌套文档查询
db.users.find({ "address.city": "北京" })// 聚合查询
db.users.aggregate([{ $group: { _id: "$age", count: { $sum: 1 } } },{ $sort: { count: -1 } }
])
进阶篇
六、MongoDB索引
6.1 索引操作
// 创建索引
db.users.createIndex({ email: 1 })// 创建唯一索引
db.users.createIndex({ email: 1 }, { unique: true })// 创建复合索引
db.users.createIndex({ name: 1, age: -1 })// 查看索引
db.users.getIndexes()// 删除索引
db.users.dropIndex({ email: 1 })
6.2 索引类型
- 单字段索引
- 复合索引
- 多键索引
- 文本索引
- 地理空间索引
- 哈希索引
七、MongoDB聚合操作
7.1 聚合管道
// 基本聚合
db.users.aggregate([{ $match: { age: { $gt: 25 } } },{ $group: { _id: "$age", count: { $sum: 1 } } },{ $sort: { count: -1 } }
])// 复杂聚合
db.orders.aggregate([{ $match: { status: "completed" } },{ $group: {_id: "$customer_id",total: { $sum: "$amount" },count: { $sum: 1 }}},{ $lookup: {from: "customers",localField: "_id",foreignField: "_id",as: "customer"}},{ $unwind: "$customer" },{ $project: {customer_name: "$customer.name",total: 1,count: 1}}
])
7.2 聚合操作符
- $match:过滤文档
- $group:分组
- $sort:排序
- $limit:限制
- $skip:跳过
- $project:投影
- $lookup:关联查询
- $unwind:展开数组
八、MongoDB数据模型
8.1 文档模型
// 嵌入式文档
{_id: ObjectId("..."),name: "张三",orders: [{order_id: "001",amount: 100,items: [{ product: "手机", quantity: 1 },{ product: "耳机", quantity: 2 }]}]
}// 引用式文档
{_id: ObjectId("..."),name: "张三",order_ids: [ObjectId("..."),ObjectId("...")]
}
8.2 数据关系
- 一对一关系
- 一对多关系
- 多对多关系
九、MongoDB安全
9.1 用户管理
// 创建用户
db.createUser({user: "admin",pwd: "password",roles: ["userAdminAnyDatabase"]
})// 修改用户
db.updateUser("admin", {roles: ["userAdminAnyDatabase", "readWriteAnyDatabase"]
})// 删除用户
db.dropUser("admin")
9.2 访问控制
// 启用认证
security:authorization: enabled// 设置访问权限
db.grantRolesToUser("user", ["readWrite"])
十、MongoDB备份恢复
10.1 备份操作
# 备份整个数据库
mongodump --db mydb --out /backup# 备份特定集合
mongodump --db mydb --collection users --out /backup# 压缩备份
mongodump --db mydb --gzip --archive=/backup/backup.gz
10.2 恢复操作
# 恢复整个数据库
mongorestore --db mydb /backup/mydb# 恢复特定集合
mongorestore --db mydb --collection users /backup/mydb/users.bson# 恢复压缩备份
mongorestore --gzip --archive=/backup/backup.gz
十一、MongoDB性能优化
11.1 查询优化
- 使用索引
- 限制返回字段
- 使用投影
- 使用分页
- 避免使用正则表达式
11.2 索引优化
- 创建合适的索引
- 避免过多索引
- 使用复合索引
- 定期维护索引
11.3 配置优化
# mongod.conf
storage:wiredTiger:engineConfig:cacheSizeGB: 4collectionConfig:blockCompressor: snappyoperationProfiling:mode: slowOpslowOpThresholdMs: 100replication:oplogSizeMB: 10240
十二、MongoDB高级特性
12.1 Change Streams
// 监听集合变化
const changeStream = db.collection('users').watch();
changeStream.on('change', (change) => {console.log('检测到变化:', change);
});// 使用管道过滤器
const pipeline = [{ $match: { 'operationType': 'insert' } }
];
const filteredStream = db.collection('users').watch(pipeline);
12.2 事务处理
// 开启事务
const session = db.getMongo().startSession();
session.startTransaction();try {// 转账操作示例db.accounts.updateOne({ userId: "user1" },{ $inc: { balance: -100 } },{ session });db.accounts.updateOne({ userId: "user2" },{ $inc: { balance: 100 } },{ session });await session.commitTransaction();
} catch (error) {await session.abortTransaction();throw error;
} finally {session.endSession();
}
12.3 GridFS文件存储
// 存储大文件
const bucket = new GridFSBucket(db);
fs.createReadStream('video.mp4').pipe(bucket.openUploadStream('video.mp4'));// 读取文件
bucket.openDownloadStreamByName('video.mp4').pipe(fs.createWriteStream('downloaded-video.mp4'));
十三、MongoDB复制集
13.1 复制集配置
# mongod.conf
replication:replSetName: "myReplicaSet"
// 初始化复制集
rs.initiate({_id: "myReplicaSet",members: [{ _id: 0, host: "mongodb1:27017" },{ _id: 1, host: "mongodb2:27017" },{ _id: 2, host: "mongodb3:27017" }]
});// 查看复制集状态
rs.status();// 添加节点
rs.add("mongodb4:27017");// 移除节点
rs.remove("mongodb4:27017");
13.2 复制集运维
// 主节点降级
rs.stepDown();// 设置优先级
cfg = rs.conf();
cfg.members[0].priority = 2;
rs.reconfig(cfg);// 设置隐藏节点
cfg.members[2].hidden = true;
cfg.members[2].priority = 0;
rs.reconfig(cfg);
十四、MongoDB分片集群
14.1 分片集群架构
- Config Server(配置服务器)
- Shard Server(分片服务器)
- Mongos Router(路由服务器)
14.2 分片配置
// 启用分片
sh.enableSharding("mydb");// 对集合进行分片
sh.shardCollection("mydb.users", { userId: "hashed" });// 范围分片
sh.shardCollection("mydb.orders", { orderDate: 1 });// 复合分片键
sh.shardCollection("mydb.products", { category: 1, price: 1 });
应用篇
十五、MongoDB性能诊断
15.1 查询分析
// 执行计划分析
db.users.find({ age: { $gt: 25 } }).explain("executionStats");// 慢查询分析
db.setProfilingLevel(1, { slowms: 100 });
db.system.profile.find().sort({ ts: -1 });// 查询统计
db.users.aggregate([{ $indexStats: {} }
]);
15.2 性能监控
// 服务器状态
db.serverStatus();// 数据库统计
db.stats();// 集合统计
db.users.stats();// 连接情况
db.currentOp();
十六、MongoDB数据迁移
16.1 数据导出
# 导出JSON格式
mongoexport --db mydb --collection users --out users.json# 导出CSV格式
mongoexport --db mydb --collection users --type=csv --fields name,age,email --out users.csv# 条件导出
mongoexport --db mydb --collection users --query '{"age":{"$gt":25}}' --out users_filtered.json
16.2 数据导入
# 导入JSON
mongoimport --db mydb --collection users --file users.json# 导入CSV
mongoimport --db mydb --collection users --type csv --headerline --file users.csv# 导入时进行转换
mongoimport --db mydb --collection users --file users.json --transform 'this.age = Number(this.age)'
十七、MongoDB应用开发最佳实践
17.1 数据建模
// 反范式设计示例
{_id: ObjectId("..."),orderId: "ORD001",customer: {name: "张三",email: "zhangsan@example.com",address: "北京市朝阳区"},items: [{productId: "P001",name: "iPhone",price: 6999,quantity: 1}],totalAmount: 6999,status: "completed"
}
17.2 查询优化技巧
// 使用覆盖索引
db.users.find({ age: { $gt: 25 } },{ _id: 0, name: 1, age: 1 }
).hint({ age: 1, name: 1 });// 使用投影减少网络传输
db.users.find({ },{ name: 1, age: 1, _id: 0 }
);// 批量操作
db.users.bulkWrite([{ insertOne: { document: { name: "张三", age: 25 } } },{ updateOne: { filter: { name: "李四" },update: { $set: { age: 26 } }} },{ deleteOne: { filter: { name: "王五" } } }
]);
17.3 错误处理
try {// 插入唯一索引冲突处理await db.users.insertOne({email: "existing@example.com",name: "张三"});
} catch (error) {if (error.code === 11000) {console.log('邮箱已存在');} else {throw error;}
}
十八、MongoDB运维管理
18.1 日志管理
# mongod.conf
systemLog:destination: filepath: "/var/log/mongodb/mongod.log"logAppend: truelogRotate: rename
18.2 监控告警
// 设置告警阈值
db.createCollection("alerts");
db.alerts.createIndex({ "timestamp": 1 }, { expireAfterSeconds: 86400 });// 监控连接数
const connections = db.serverStatus().connections;
if (connections.current > connections.available * 0.8) {db.alerts.insertOne({type: "connection_warning",message: "连接数超过80%",timestamp: new Date()});
}
18.3 容量规划
- 评估数据增长率
- 监控磁盘使用情况
- 规划扩容时机
- 制定备份策略
十九、MongoDB常见应用场景示例
19.1 用户管理系统
// 用户注册
db.users.insertOne({用户名: "xiaoming",密码: "123456", // 实际应用中要加密注册时间: new Date(),最后登录: new Date(),状态: "正常"
})// 用户登录验证
db.users.findOne({用户名: "xiaoming",密码: "123456"
})// 更新登录时间
db.users.updateOne({用户名: "xiaoming"},{$set: {最后登录: new Date()}}
)
19.2 商品评论系统
// 添加评论
db.comments.insertOne({商品ID: "prod123",用户名: "xiaoming",评分: 5,内容: "很好用!",评论时间: new Date(),点赞数: 0
})// 查看商品评论
db.comments.find({商品ID: "prod123"})// 给评论点赞
db.comments.updateOne({_id: "评论ID"},{$inc: {点赞数: 1}} // $inc表示增加
)
19.3 内容管理系统
// 创建文章
db.articles.insertOne({标题: "MongoDB入门指南",作者: "xiaoming",内容: "MongoDB是一个文档型数据库...",标签: ["数据库", "NoSQL", "MongoDB"],创建时间: new Date(),更新时间: new Date(),阅读量: 0,点赞数: 0
})// 更新文章
db.articles.updateOne({标题: "MongoDB入门指南"},{$set: {更新时间: new Date()},$inc: {阅读量: 1}}
)// 按标签查询文章
db.articles.find({标签: "MongoDB"})
19.4 日志系统
// 记录系统日志
db.logs.insertOne({级别: "ERROR",模块: "用户认证",消息: "用户登录失败",详情: "密码错误",时间: new Date(),用户ID: "user123",IP地址: "192.168.1.1"
})// 查询错误日志
db.logs.find({级别: "ERROR"})// 按时间范围查询
db.logs.find({时间: {$gte: new Date(new Date().setDate(new Date().getDate() - 7)),$lte: new Date()}
})
二十、MongoDB与Java集成
20.1 MongoDB Java驱动
// 添加MongoDB Java驱动依赖
// Maven
<dependency><groupId>org.mongodb</groupId><artifactId>mongodb-driver-sync</artifactId><version>4.11.1</version>
</dependency>// Gradle
implementation 'org.mongodb:mongodb-driver-sync:4.11.1'
20.2 连接MongoDB
// 创建MongoDB客户端
MongoClient mongoClient = MongoClients.create("mongodb://localhost:27017");// 获取数据库
MongoDatabase database = mongoClient.getDatabase("mydb");// 获取集合
MongoCollection<Document> collection = database.getCollection("users");// 关闭连接
mongoClient.close();
20.3 基本操作示例
// 插入文档
Document document = new Document("name", "张三").append("age", 25).append("email", "zhangsan@example.com");
collection.insertOne(document);// 查询文档
Document query = new Document("name", "张三");
Document result = collection.find(query).first();
System.out.println(result.toJson());// 更新文档
Document updateQuery = new Document("name", "张三");
Document update = new Document("$set", new Document("age", 26));
collection.updateOne(updateQuery, update);// 删除文档
Document deleteQuery = new Document("name", "张三");
collection.deleteOne(deleteQuery);
20.4 使用MongoDB Java驱动的高级功能
// 批量操作
List<WriteModel<Document>> writes = new ArrayList<>();
writes.add(new InsertOneModel<>(new Document("name", "李四").append("age", 30)));
writes.add(new UpdateOneModel<>(new Document("name", "王五"),new Document("$set", new Document("age", 28))
));
writes.add(new DeleteOneModel<>(new Document("name", "赵六")));BulkWriteResult bulkWriteResult = collection.bulkWrite(writes);
System.out.println("插入: " + bulkWriteResult.getInsertedCount());
System.out.println("更新: " + bulkWriteResult.getModifiedCount());
System.out.println("删除: " + bulkWriteResult.getDeletedCount());// 聚合操作
List<Document> pipeline = Arrays.asList(new Document("$match", new Document("age", new Document("$gt", 25))),new Document("$group", new Document("_id", "$age").append("count", new Document("$sum", 1))),new Document("$sort", new Document("count", -1))
);MongoCursor<Document> cursor = collection.aggregate(pipeline).iterator();
while (cursor.hasNext()) {System.out.println(cursor.next().toJson());
}
二十一、MongoDB与Spring Boot集成
21.1 添加Spring Data MongoDB依赖
<!-- Maven -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency><!-- Gradle -->
implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
21.2 配置MongoDB连接
# application.yml
spring:data:mongodb:uri: mongodb://localhost:27017/mydb# 或者使用以下配置# host: localhost# port: 27017# database: mydb# username: admin# password: password
21.3 创建实体类
@Document(collection = "users")
public class User {@Idprivate String id;private String name;private int age;private String email;private List<String> hobbies;private Address address;// 构造函数、getter和setter方法// 内部类public static class Address {private String city;private String street;// 构造函数、getter和setter方法}
}
21.4 创建Repository接口
@Repository
public interface UserRepository extends MongoRepository<User, String> {// 自定义查询方法List<User> findByAgeGreaterThan(int age);List<User> findByNameStartingWith(String prefix);Optional<User> findByEmail(String email);// 使用@Query注解自定义查询@Query("{ 'age' : { $gt : ?0, $lt : ?1 } }")List<User> findByAgeBetween(int minAge, int maxAge);
}
21.5 使用MongoDB Template
@Service
public class UserService {@Autowiredprivate MongoTemplate mongoTemplate;public List<User> findUsersByAge(int age) {Query query = new Query(Criteria.where("age").gt(age));return mongoTemplate.find(query, User.class);}public void updateUserAge(String id, int newAge) {Query query = new Query(Criteria.where("id").is(id));Update update = new Update().set("age", newAge);mongoTemplate.updateFirst(query, update, User.class);}public List<User> aggregateUsersByAge() {Aggregation aggregation = Aggregation.newAggregation(Aggregation.match(Criteria.where("age").gt(25)),Aggregation.group("age").count().as("count"),Aggregation.sort(Sort.Direction.DESC, "count"));AggregationResults<User> results = mongoTemplate.aggregate(aggregation, "users", User.class);return results.getMappedResults();}
}
二十二、MongoDB与Docker部署
22.1 使用Docker运行MongoDB
# 拉取MongoDB镜像
docker pull mongo:latest# 运行MongoDB容器
docker run -d --name mongodb -p 27017:27017 mongo:latest# 运行MongoDB容器(带数据持久化)
docker run -d --name mongodb -p 27017:27017 -v /data/mongodb:/data/db mongo:latest# 运行MongoDB容器(带认证)
docker run -d --name mongodb -p 27017:27017 -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=password mongo:latest
22.2 使用Docker Compose部署MongoDB
# docker-compose.yml
version: '3'
services:mongodb:image: mongo:latestcontainer_name: mongodbports:- "27017:27017"volumes:- ./data:/data/dbenvironment:- MONGO_INITDB_ROOT_USERNAME=admin- MONGO_INITDB_ROOT_PASSWORD=passwordnetworks:- mongo-networkmongo-express:image: mongo-express:latestcontainer_name: mongo-expressports:- "8081:8081"environment:- ME_CONFIG_MONGODB_ADMINUSERNAME=admin- ME_CONFIG_MONGODB_ADMINPASSWORD=password- ME_CONFIG_MONGODB_URL=mongodb://admin:password@mongodb:27017/depends_on:- mongodbnetworks:- mongo-networknetworks:mongo-network:driver: bridge
22.3 使用Docker部署MongoDB复制集
# docker-compose-replica.yml
version: '3'
services:mongodb1:image: mongo:latestcontainer_name: mongodb1command: mongod --replSet rs0 --bind_ip_allports:- "27017:27017"volumes:- ./data1:/data/dbnetworks:- mongo-networkmongodb2:image: mongo:latestcontainer_name: mongodb2command: mongod --replSet rs0 --bind_ip_allports:- "27018:27017"volumes:- ./data2:/data/dbnetworks:- mongo-networkmongodb3:image: mongo:latestcontainer_name: mongodb3command: mongod --replSet rs0 --bind_ip_allports:- "27019:27017"volumes:- ./data3:/data/dbnetworks:- mongo-networknetworks:mongo-network:driver: bridge
# 初始化复制集
docker exec -it mongodb1 mongosh --eval "rs.initiate({_id: 'rs0',members: [{_id: 0, host: 'mongodb1:27017'},{_id: 1, host: 'mongodb2:27017'},{_id: 2, host: 'mongodb3:27017'}]
})"
最佳实践篇
二十三、MongoDB常见问题解答
23.1 连接问题
问题: 无法连接到MongoDB服务器
解决方案:
- 检查MongoDB服务是否正在运行
- 检查防火墙设置,确保端口27017开放
- 检查MongoDB配置文件中的bindIp设置
- 如果使用认证,确保用户名和密码正确
23.2 性能问题
问题: MongoDB查询速度慢
解决方案:
- 为常用查询字段创建索引
- 使用explain()分析查询执行计划
- 优化查询,只返回需要的字段
- 检查服务器资源使用情况(CPU、内存、磁盘I/O)
- 考虑增加服务器资源或使用分片集群
23.3 数据一致性问题
问题: 在复制集中出现数据不一致
解决方案:
- 检查复制集状态:
rs.status()
- 检查主节点和从节点的数据差异
- 如果从节点落后太多,考虑重新同步
- 确保网络连接稳定,避免网络分区
23.4 内存问题
问题: MongoDB占用过多内存
解决方案:
- 调整WiredTiger缓存大小
- 监控内存使用情况
- 考虑增加服务器内存
- 优化查询和索引,减少内存使用
23.5 磁盘空间问题
问题: MongoDB磁盘空间不足
解决方案:
- 清理不需要的数据
- 压缩集合:
db.runCommand({compact: "collection_name"})
- 增加磁盘空间
- 考虑使用分片集群分散数据
二十四、MongoDB最佳实践总结
24.1 数据建模最佳实践
-
嵌入vs引用
- 一对少关系:使用嵌入
- 一对多关系:根据查询模式决定
- 多对多关系:通常使用引用
-
文档大小
- 保持文档大小在16MB以下
- 避免过深的嵌套(不超过3-4层)
- 避免过大的数组
-
字段命名
- 使用简短但有意义的字段名
- 保持命名风格一致
- 避免使用特殊字符
24.2 查询优化最佳实践
-
索引策略
- 为所有查询创建适当的索引
- 避免过多索引(每个集合不超过64个)
- 使用复合索引支持多字段查询
- 考虑索引顺序(等值查询字段放在前面)
-
查询模式
- 使用覆盖索引减少内存使用
- 使用投影只返回需要的字段
- 使用批量操作代替多次单文档操作
- 避免使用正则表达式进行前缀查询
24.3 运维最佳实践
-
监控
- 监控服务器资源使用情况
- 监控查询性能
- 监控复制集状态
- 设置告警阈值
-
备份
- 定期备份数据
- 测试恢复流程
- 保存备份记录
- 考虑使用云服务提供商的备份功能
-
安全
- 启用认证
- 限制网络访问
- 定期更新密码
- 使用TLS/SSL加密传输
-
扩展
- 垂直扩展:增加服务器资源
- 水平扩展:使用分片集群
- 根据数据增长和访问模式规划扩展策略
24.4 应用开发最佳实践
-
连接管理
- 使用连接池
- 正确关闭连接
- 处理连接异常
-
错误处理
- 捕获并处理MongoDB异常
- 实现重试机制
- 记录错误日志
-
事务使用
- 只在必要时使用事务
- 保持事务简短
- 考虑使用补偿事务代替长时间运行的事务
-
代码组织
- 使用数据访问层封装MongoDB操作
- 使用ORM框架简化开发
- 遵循领域驱动设计原则
相关文章:
MongoDB基础知识
MongoDB基础知识 目录 基础篇 一、MongoDB入门指南(零基础必读)二、MongoDB简介三、MongoDB安装与配置四、MongoDB基本操作五、MongoDB查询操作 进阶篇 六、MongoDB索引七、MongoDB聚合操作八、MongoDB数据模型九、MongoDB安全十、MongoDB备份恢复十一…...
Kubernetes详细教程(一):入门、架构及基本概念
Kubernetes(常简称为K8s)是一个开源的平台,用于自动化部署、扩展和管理容器化应用程序。 官方文档:https://kubernetes.io/zh-cn/docs/concepts/overview/components/ 一、入门 (一)Kubernetes是什么&am…...
架构思维:限流技术深度解析
文章目录 Pre业务场景熔断 VS 限流4大限流算法固定时间窗口计数滑动时间窗口计数漏桶令牌桶 方案实现使用令牌桶还是漏桶模式?在 Nginx 中实现限流还是在网关层中实现限流?使用分布式限流还是单机限流?使用哪个开源技术? 限流方案…...
批量改CAD图层颜色——CAD c#二次开发
一个文件夹下大量图纸(几百甚至几千个文件)需要改图层颜色时,可采用插件实现,效果如下: 转换前: 转换后: 使用方式如下:netload加载此dll插件,输入xx运行。 附部分代码如…...
vue猜词游戏
说明:我希望用vue实现猜词游戏 Vue Wordle 游戏规则总结 核心规则 单词选择 目标单词从预设词库(DEFAULT_WORDS)中随机选取,均为5字母单词(如apple、zebra等)。 输入要求 长度限制:必须…...
SQL ②-库操作 | 数据类型
这里是Themberfue SQL语法 数据库术语 DATABASE:数据库,保存有组织的数据的容器(通常是一个文件或一组文件)。TABLE:表,某种特定类型数据的结构化清单。SCHEMA:模式,关于数据库和表…...
云轴科技ZStack CTO王为@中国GenAI大会:AI原生实践重构AI Infra新范式
4月1-2日,2025中国生成式AI大会(GenAICon 2025)在北京举办,该会议已成为国内AI领域最具影响力的产业峰会之一。来自学术界与产业界的50位嘉宾围绕GenAI应用、大模型、AI智能体、具身智能、DeepSeek R1与推理模型等话题,…...
处理甘特图启动依赖报错。
处理甘特图启动报错 一、修改甘特图下载地址1.1 配置修改1.2 修改地址(https://registry.npmmirror.com) 二、安装依赖1.1 安装sass-loader1.2 适配安装dhtmlx-gantt 一、修改甘特图下载地址 1.1 配置修改 npm config get registry1.2 修改地址(https://registry.npmmirror.c…...
JSX、支持HTML标签、Ref的使用、虚拟DOM的使用
🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 🍚 蓝桥云课签约作者、…...
leetcode376-摆动序列
leetcode 376 思路 变量定义: prediff:记录上一次相邻元素的差值。用于判断当前差值与上一个差值的关系curdiff:记录当前相邻元素的差值result:记录当前的摆动序列的长度,初始化为 1,因为至少一个元素就…...
内网渗透(杂项集合) --- 中的多协议与漏洞利用技术(杂项知识点 重点) 持续更新
目录 1. NetBIOS 名称的网络协议在局域网中内网渗透中起到什么作用 2. 使用 UDP 端口耗尽技术强制所有 DNS 查找失败,这个技术如何应用在局域网内网渗透测试中 3. 在本地创建一个 HTTP 服务来伪造 WPAD 服务器 什么是 WPAD 服务器?这个服务器是干嘛的…...
14-产品经理-维护计划
产品经理的另一个职责是制定计划。古人云,凡事预则立,不预则废。 产品需要做规划,才能有轻重缓急,才能正确的做事。因此对于产品经理而言,计划是必需的。 对于产品经理自己而言,发布计划可以帮助他规划产…...
12-产品经理-维护模块
需求模块是帮助产品经理进行需求的分类和维护。 1. 维护模块 在具体产品的“研发需求”页面左侧,点击“维护模块”。也可以在具体产品的“设置”-“模块”下进行维护。 点击保存后,返回模块页面。还可以点击“子模块”对已有模块进行子模块的维护。 点击…...
解析HiveQL的ALTER TABLE ADD/REPLACE COLUMNS语句
阅读以下ALTER TABLE的ADD/REPLACE COLUMNS语句的语法,用C#编写解析函数,一个一个字符解析,所有关键字不区分大小写,一个或多个空格、Tab和换行的组合都可以是关键词之间的分隔,表名和字段名可能包含空格和Tab…...
MySQL-SQL-DML语句、INSER添加数据、UPDATE更新数据、DELETE删除数据
一. DML 1. DML的英文全称是Data Manipulation Language(数据操作语言),用来对数据库中表的数据记录进行增、删、改操作。 2. 添加数据(INSERT);修改数据(UPDATE);删除数据(DELETE) 二. DML-INSER添加数据 -- DML insert -- 指定字段添加数…...
学透Spring Boot — 017. 处理静态文件
这是我的《学透Spring Boot》专栏的第17篇文章,了解更多内容请移步我的专栏: Postnull CSDN 学透 Spring Boot 目录 静态文件 静态文件的默认位置 通过配置文件配置路径 通过代码配置路径 静态文件的自动配置 总结 静态文件 以前的传统MVC的项目…...
Linux进程间通信——共享内存
1.概念 共享内存(Shared Memory)就是允许多个进程访问同一个内存空间,是在多个进程之间共享和传递数据最高效的方式。操作系统将不同进程之间共享内存安排为同一段物理内存,进程可以将共享内存连接到它们自己的地址空间中&#x…...
如何在大型项目中组织和管理 Vue 3 Hooks?
众所周知,Vue Hooks(通常指 Composition API 中的功能)是 Vue 3 引入的一种代码组织方式,用于更灵活地组合和复用逻辑。但是在项目中大量使用这种写法该如何更好的搭建结构呢?以下是可供参考实践的案例。 一、Hooks 组织原则 单一职责每个 Hook 应专注于完成单一功能,避…...
前后端开发的未来趋势
随着技术的不断进步,前后端开发模式也在不断演变。未来,微服务架构、Serverless、前后端融合(GraphQL、BFF)等趋势将深刻影响开发方式,使应用更高效、灵活、可扩展。 1. 微服务架构与 Serverless 1.1 微服务架构(Microservices Architecture) 微服务是一种软件架构模式…...
产品经理课程
原型工具 一、土耳其机器人 这个说法来源于 1770 年出现的一个骗局,一个叫沃尔夫冈冯肯佩伦(Wolfgang von Kempelen)的人为了取悦奥地利女皇玛丽娅特蕾莎(Maria Theresia),“制造”了一个会下国际象棋的机…...
【开源宝藏】30天学会CSS - DAY12 第十二课 从左向右填充的文字标题动画
用伪元素搞定文字填充动效:一行 JS 不写,效果炸裂 你是否曾经在设计页面标题时,觉得纯文字太寡淡?或者想做一个有动感的文字特效,但又不想引入 JS 甚至 SVG? 在这篇文章中,我们将通过 一段不到…...
Nginx 负载均衡案例配置
负载均衡案例 基于 docker 进行 案例测试 1、创建三个 Nginx 实例 创建目录结构 为每个 Nginx 实例创建单独的目录,用于存储 HTML 文件和配置文件 mkdir -p data/nginx1/html mkdir -p data/nginx2/html mkdir -p data/nginx3/html添加自定义 HTML 文件 在每个…...
Golang系列 - 内存对齐
Golang系列-内存对齐 常见类型header的size大小内存对齐空结构体类型参考 摘要: 本文将围绕内存对齐展开, 包括字符串、数组、切片等类型header的size大小、内存对齐、空结构体类型的对齐等等内容. 关键词: Golang, 内存对齐, 字符串, 数组, 切片 常见类型header的size大小 首…...
nginx中的limit_req 和 limit_conn
在 Nginx 中,limit_req 和 limit_conn 是两个用于限制客户端请求的指令,它们分别用于限制请求速率和并发连接数。 limit_req limit_req 用于限制请求速率,防止客户端发送过多请求影响服务器性能。它通过 limit_req_zone 指令定义一个共享内存…...
Python Cookbook-5.4 根据对应值将键或索引排序
任务 需要统计不同元素出现的次数,并且根据它们的出现次数安排它们的顺序——比如,你想制作一个柱状图。 解决方案 柱状图,如果不考虑它在图形图像上的含义,实际上是基于各种不同元素(用Python的列表或字典很容易处理)出现的次…...
U535982 J-A 小梦的AB交换
U535982 J-A 小梦的AB交换 - 洛谷 题目描述 小梦有一个长度为 2⋅n 的 AB 串 s,即 s 中只包含 "A" 和 "B" 两种字符,且其中恰好有 n 个 "A" 和 n 个 "B"。 他可以对 s 执行以下操作: 选择 i,j (…...
2025高频面试算法总结篇【排序】
文章目录 直接刷题链接直达把数组排成最小的数删除有序数组中的重复项求两个排序数组的中位数求一个循环递增数组的最小值数组中的逆序对如何找到一个无序数组的中位数链表排序从一大段文本中找出TOP K 的高频词汇 直接刷题链接直达 把一个数组排成最大的数 剑指 Offer 45. 把…...
计算机视觉基础4——特征点及其描述子
一、特征点检测 (一)特征点定义 图像中具有独特局部性质的点。 (二)特征点性质 具有局部性(对遮挡和混乱场景鲁棒)、数量足够多(一幅图像可产生成百上千个)、独特性(…...
React 初学者进阶指南:从环境搭建到部署上线
概览 环境搭建 核心概念 TodoList 实战 部署上线 一、快速搭建 React 开发环境 1. 选型:Vite 或 Create React App Vite:轻量、热更新速度快、可定制度高,适合追求更高效率的开发者。Create React App (CRA):社区支持全面,文档丰富,适合初学者上手。我使用的是Vite 提示…...
docker加docker compose实现软件快速安装启动
docker 下载镜像官网页面:https://hub.docker.com/ docker是什么? 加速应用构建、分享、运行 docker命令 镜像操作 容器操作 docker ps:查看运行中的容器 docker ps -a: 查看所有容器,包括停止的 除了docker run和docker exec两个命令其余执…...
使用人工智能大模型腾讯元宝,如何免费快速做工作总结?
今天我们学习使用人工智能大模型腾讯元宝,如何免费快速做工作总结? 手把手学习视频地址:https://edu.csdn.net/learn/40402/666429 第一步在腾讯元宝对话框中输入如何协助老师做工作总结,通过提问,我们了解了老师做工…...
【小兔鲜】day03 Home模块与一级分类
【小兔鲜】day03 Home模块与一级分类 1. Home-整体结构搭建和分类实现1.1 页面结构 2. Home-banner轮播图功能实现 1. Home-整体结构搭建和分类实现 1.1 页面结构 分类实现 2. Home-banner轮播图功能实现 轮播图实现 在HomeBanner.vue中写出轮播图的结构 在apis目录下新建h…...
c++使用gstreamer录屏+声音
说明: c使用gstreamer完成录制电脑桌面的功能 我希望用gstreamer录屏,默认10秒,自动保存录屏文件到本地 这里是不带声音的版本,仅录屏, step1:C:\Users\wangrusheng\source\repos\CMakeProject1\CMakeProject1\CMakeL…...
PowerToys:Windows高效工具集
Microsoft PowerToys 是微软官方推出的 免费开源效率工具集,专为 Windows 系统设计,通过模块化功能解决高频操作痛点,提升用户生产力。支持 Windows 10/11 系统,覆盖开发者、设计师及普通办公场景。 一、核心功能亮点 高…...
pulsar中的延迟队列使用详解
Apache Pulsar的延迟队列支持任意时间精度的延迟消息投递,适用于金融交易、定时提醒等高时效性场景。其核心设计通过堆外内存索引队列与持久化分片存储实现,兼顾灵活性与可扩展性。以下从实现原理、使用方式、优化策略及挑战展开解析: 一、核…...
import torch 失败
1. 使用 PyTorch 官方 Conda 频道安装 运行以下命令(根据你的 CUDA 版本选择): # CPU 版本 conda install pytorch torchvision torchaudio cpuonly -c pytorch# CUDA 11.8 版本 conda install pytorch torchvision torchaudio pytorch-cud…...
什么是异步?
什么是异步? 异步是一个术语,用于描述不需要同时行动或协调就能独立运行的流程。这一概念在技术和计算领域尤为重要,它允许系统的不同部分按自己的节奏运行,而无需等待同步信号或事件。在区块链技术中,异步是指网络中…...
Llama 4 家族:原生多模态 AI 创新新时代的开启
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
情感语音的“开源先锋”!网易开源
语音合成技术近年来取得了显著进步,特别是在语音克隆、语音助手、配音服务和有声读物等领域。然而,如何让合成的语音更具情感,更贴近人类的真实表达,一直是这一领域的重要研究方向。今天,我们将为大家介绍一款由网易有…...
消息队列基础概念及选型,常见解决方案包括消息可靠性、消息有序、消息堆积、重复消费、事务消息
前言 是时候总结下消息队列相关知识点啦!我搓搓搓搓 本文包括消息队列基础概念介绍,常见解决方案包括消息可靠性、消息有序、消息堆积、重复消费、事务消息 参考资料: Kafka常见问题总结 | JavaGuide RocketMQ常见问题总结 | JavaGuide …...
子类是否能继承
继承 父类: 子 类 构造方法 非私有 不能继承 私有(private)不能继承 成员变量 非私有 能继承 私有&…...
计算机系统--- BIOS(基本输入输出系统)
一、BIOS的定义与核心定位 BIOS(Basic Input/Output System)是计算机启动时运行的底层固件,存储在主板的ROM芯片中。它是连接硬件与操作系统的桥梁,负责初始化硬件、加载启动程序,并提供基础配置界面。其核心目标是&a…...
Ollama 与 llama.cpp 深度对比
Ollama 与 llama.cpp 深度对比 1. 定位与架构 维度llama.cppOllama核心定位Meta LLaMA 的 C 推理框架,专注底层优化基于 llama.cpp 的高层封装工具,提供一站式服务技术栈纯 C 实现,支持量化/内存管理/硬件指令集优化(AVX/NEON/M…...
C++ —— 智能指针
C ——智能指针 智能指针存在的必要性1. 解决内存泄漏问题2. 避免悬垂指针(Dangling Pointer)3. 异常安全性 std::unique_ptr (独占所有权)代码功能说明关键点解析内存管理流程对比传统指针为何使用 make_unique? uniq…...
Go语言的测试框架
Go语言测试框架详解 Go语言(Golang)自发布以来,因其简洁、高效和并发支持而受到广泛欢迎。在软件开发过程中,测试是确保代码质量与稳定性的重要环节。Go语言内置的测试框架为开发者提供了灵活而强大的测试工具,使得编…...
配置多区域集成IS-IS和抓包分析
基本概念 IS-IS区域结构: 使用两级层次结构:Level 1(区域内)和Level 2(区域间) Level 1路由器了解本区域拓扑 Level 2路由器在不同区域间传输流量 Level 1-2路由器同时执行两种功能 NSAP地址ÿ…...
网络原理 - HTTP/HTTPS
1. HTTP 1.1 HTTP是什么? HTTP (全称为 “超文本传输协议”) 是⼀种应用非常广泛的应用层协议. HTTP发展史: HTTP 诞生于1991年. 目前已经发展为最主流使用的⼀种应用层协议 最新的 HTTP 3 版本也正在完善中, 目前 Google / Facebook 等公司的产品已经…...
JavaScript逆向WebSocket协议解析与动态数据抓取
在JavaScript逆向工程中,WebSocket协议的解析和动态数据抓取是关键技能。本文将结合Fiddler、Charles Proxy和APIfox工具,详细讲解如何解析WebSocket协议并抓取动态数据。 一、WebSocket协议解析 (一)WebSocket协议的基本概念 …...
过滤震荡行行策略思路
本文讨论的是如何识别和过滤金融市场中的震荡行情,特别是对于趋势交易者来说,如何避免在震荡行情中频繁止损和资金回撤。 主要观点 震荡行情的定义 - 行情在有序与无序之间的中间状态,由多空力量不足导致的横盘。 震荡行情的分类 - 宽幅震…...
消息队列(kafka 与 rocketMQ)
为什么要使用消息队列?作用1: 削峰填谷(突发大请求量问题)作用2: 解耦(单一原则)作用3: 异步(减少处理时间) 如何选择消息队列(kafka&RocketMQ)成本功能性能选择 rocketMQ是参考kafka进行实现的为什么rocketMQ与kafka性能差距很大呢?kafka 的底层数据储存实现rocketMQ 的…...