C#与MongoDB.Driver实战指南:从零掌握文档查询的核心技巧
一、为什么需要关注MongoDB查询操作?
假设你有一个装满杂物的储物间(MongoDB数据库),每次找东西(查询文档)都要翻箱倒柜。MongoDB.Driver就像是一套智能标签系统,帮你快速定位目标物品。作为C#开发者,掌握这个工具能让你在NoSQL领域游刃有余。
二、环境准备与基础连接
技术栈:C# 10 + MongoDB.Driver 2.19.1 + MongoDB 6.0
// 创建MongoClient实例(连接池已自动启用)
var client = new MongoClient("mongodb://localhost:27017");
// 获取数据库和集合对象
var database = client.GetDatabase("shopDB");
var collection = database.GetCollection<Product>("products");
/* 注释说明:
1. Product是自定义的C#类,需与集合文档结构对应
2. 连接字符串支持副本集、分片集群等复杂配置
*/
三、六大核心查询操作详解
3.1 基础查询:获取所有文档
// 查询所有价格大于100的商品
var filter = Builders<Product>.Filter.Gt(p => p.Price, 100);
var results = await collection.Find(filter).ToListAsync();
/* 等效MongoDB原生查询:
{ "price" : { "$gt" : 100 } }
*/
3.2 精确查询与投影
// 只获取名称和库存字段
var projection = Builders<Product>.Projection
.Include(p => p.Name)
.Include(p => p.Stock);
var items = collection.Find(_ => true)
.Project<Product>(projection)
.Limit(10);
3.3 复合条件查询
// 组合查询:品类为电子,且评分4星以上
var complexFilter = Builders<Product>.Filter.And(
Builders<Product>.Filter.Eq(p => p.Category, "Electronics"),
Builders<Product>.Filter.Gte(p => p.Rating, 4.0)
);
3.4 排序与分页
// 按价格降序排列,跳过前20条取10条
var pagedResults = collection.Find(_ => true)
.SortByDescending(p => p.Price)
.Skip(20)
.Limit(10);
3.5 聚合查询
// 统计各品类商品数量
var aggregation = collection.Aggregate()
.Group(p => p.Category,
g => new { Category = g.Key, Count = g.Count() });
3.6 索引提示
// 强制使用name索引
var options = new FindOptions<Product> {
Hint = "name_1"
};
var withIndex = collection.Find(_ => true, options);
四、典型应用场景剖析
- 电商系统:商品的多维度筛选(价格区间、品类、评分)
- 日志分析:按时间范围查询错误日志
- 社交平台:用户动态的实时分页加载
- 物联网系统:传感器数据的聚合统计
五、技术方案优劣对比
优势:
- 原生BSON支持,避免ORM转换损耗
- 完善的异步API(async/await)
- 丰富的查询构建器(强类型Lambda)
- 官方维护,版本更新及时
局限:
- 复杂聚合语句学习曲线较陡
- 事务处理需要副本集支持
- 缺乏类似EF Core的迁移工具
六、避坑指南与最佳实践
- 连接管理:避免频繁创建MongoClient实例
// 错误做法:每次查询都new MongoClient()
// 正确做法:单例复用(线程安全)
- 索引策略:为常用查询字段建立组合索引
db.products.createIndex({ "category": 1, "price": -1 })
数据类型匹配:注意C#的DateTime与MongoDB Date的时区处理
查询优化:使用
Explain()
方法分析查询计划异常处理:捕获MongoException及其子类
try {
await collection.InsertOneAsync(newProduct);
}
catch (MongoWriteException ex) when (ex.WriteError.Code == 11000) {
// 处理唯一键冲突
}
七、总结与展望
通过MongoDB.Driver,C#开发者可以充分发挥文档数据库的灵活特性。虽然需要适应不同于关系型数据库的思维模式,但其在以下场景表现尤为突出:
- 快速迭代的需求变更
- 非结构化数据存储
- 高并发读取场景
- 分布式数据存储
未来随着.NET生态与MongoDB的深度整合,期待看到更多如实时变更流、无服务器数据库连接等创新功能的官方支持。建议开发者多关注官方文档更新,掌握第一手技术动态。