1. 环境准备与基础认知
在超市购物需要先准备购物袋,操作数据库也需要先搭建环境。我们选择MongoDB.Driver 2.18.0作为技术栈,这是目前(截至2023年)最稳定的官方驱动版本。
通过NuGet安装:
Install-Package MongoDB.Driver -Version 2.18.0
基础概念速览:
- BsonDocument:MongoDB的JSON-like数据格式
- IMongoCollection
:相当于关系型数据库中的表 - InsertOne/InsertMany:原子性写入方法
2. 数据库连接的三种姿势
2.1 基础连接模式
var client = new MongoClient("mongodb://localhost:27017");
var database = client.GetDatabase("SchoolDB");
var collection = database.GetCollection<BsonDocument>("Students");
// 等效于在Mongo Shell执行:
// use SchoolDB
// db.Students.insertOne({...})
2.2 带身份验证的连接
var settings = new MongoClientSettings {
Server = new MongoServerAddress("localhost", 27017),
Credential = MongoCredential.CreateCredential(
"admin",
"root",
"securePassword123")
};
var client = new MongoClient(settings);
2.3 云数据库连接
var connectionString = "mongodb+srv://<username>:<password>@cluster0.abcd.mongodb.net/?retryWrites=true&w=majority";
var client = new MongoClient(connectionString);
3. 文档插入的四种实战模式
3.1 基础插入(BsonDocument)
var document = new BsonDocument {
{ "name", "张三" },
{ "age", 18 },
{ "courses", new BsonArray { "数学", "物理" } },
{ "registration_date", DateTime.Now }
};
collection.InsertOne(document);
Console.WriteLine($"插入文档ID:{document["_id"]}");
/* 生成的MongoDB文档:
{
"_id": ObjectId("..."),
"name": "张三",
"age": 18,
"courses": ["数学", "物理"],
"registration_date": ISODate("2023-08-20T08:30:00Z")
}
*/
3.2 强类型插入(POCO)
定义数据模型类:
public class Student
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
[BsonElement("full_name")]
public string Name { get; set; }
[BsonElement("age")]
public int Age { get; set; }
[BsonIgnore]
public string TemporaryNote { get; set; }
}
插入操作:
var student = new Student {
Name = "李四",
Age = 20,
TemporaryNote = "需要补交材料"
};
var typedCollection = database.GetCollection<Student>("Students");
typedCollection.InsertOne(student);
Console.WriteLine($"生成的学生ID:{student.Id}");
3.3 批量插入优化
var batch = new List<BsonDocument>();
for (int i = 0; i < 1000; i++) {
batch.Add(new BsonDocument {
{ "index", i },
{ "timestamp", DateTime.Now.AddSeconds(i) }
});
}
var options = new BulkWriteOptions { IsOrdered = false };
collection.BulkWrite(batch.Select(d => new InsertOneModel<BsonDocument>(d)), options);
// 比InsertMany快3-5倍,特别适合日志类数据写入
3.4 异步插入实践
async Task InsertWithRetryAsync()
{
var document = new BsonDocument { ["data"] = "重要数据" };
try {
await collection.InsertOneAsync(document);
}
catch (MongoWriteException ex) when (ex.WriteError.Category == ServerErrorCategory.DuplicateKey) {
// 处理主键冲突
Console.WriteLine("检测到重复插入");
}
catch (TimeoutException) {
// 处理超时重试
await collection.InsertOneAsync(document);
}
}
4. 关联技术深度解析
4.1 事务处理
using (var session = client.StartSession())
{
session.StartTransaction();
try {
collection.InsertOne(session, new BsonDocument { ["type"] = "订单" });
database.GetCollection<BsonDocument>("Inventory").UpdateOne(
session,
Builders<BsonDocument>.Filter.Eq("product_id", 123),
Builders<BsonDocument>.Update.Inc("stock", -1));
session.CommitTransaction();
}
catch {
session.AbortTransaction();
throw;
}
}
4.2 插入性能调优
var settings = new MongoClientSettings {
WriteConcern = WriteConcern.W1, // 只需主节点确认
WriteEncoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false),
ServerSelectionTimeout = TimeSpan.FromSeconds(5)
};
// 适合日志场景的配置组合:
// WriteConcern.Unacknowledged + 禁用Journaling
// 最高可提升10倍写入速度
5. 应用场景全景图
- 实时日志系统:配合BulkWrite实现每秒万级写入
- 物联网数据采集:灵活Schema适应异构设备
- 用户行为分析:动态字段存储点击流数据
- 内容管理系统:嵌套文档存储文章版本历史
6. 技术优缺点分析
优势矩阵:
- 无模式设计适合快速迭代
- 原子性操作保证数据一致性
- 横向扩展能力优秀
局限所在:
- 事务支持在分片集群中存在限制
- 不适合强关系型数据场景
- 内存消耗高于传统SQL数据库
7. 注意事项备忘录
- 连接池管理:默认维持100个连接,通过
MaxConnectionPoolSize
调整 - 文档大小限制:单个文档不超过16MB
- 索引策略:在插入前建立必要索引
- 写关注级别:根据业务需求选择w=0或w=1
- 异常处理:重点监控以下错误代码:
- 11000:主键冲突
- 16500:查询超时
- 89:网络中断
8. 最佳实践总结
经过多个生产项目的验证,我们总结出以下黄金法则:
- 批量操作优先使用BulkWrite
- 重要数据必须设置WriteConcern
- 定期检查孤儿文档(通过TTL索引)
- 监控慢查询日志(profileLevel=1)
- 使用变更流(Change Stream)实现事件溯源