如何在C#中实现MongoDB的Aggregate $lookup聚合查询?
我来帮你搞定这个问题!在最新的MongoDB C#驱动(2.x及以上版本)里,QueryDocument和MongoCursor确实已经被弃用了,现在我们有更简洁、类型安全的替代方案。下面我给你两种实现思路,对应你说的直接用查询字符串和LINQ两种方式:
方式一:直接使用原始聚合查询字符串(基于BsonDocument)
这种方式适合你已经有现成的MongoDB聚合JSON查询的场景,直接把查询转换成BsonDocument数组即可,替代原来的QueryDocument。现在我们用IAggregateFluent来处理聚合结果,替代旧的MongoCursor。
示例代码如下:
using MongoDB.Bson; using MongoDB.Driver; // 假设你的主集合是"mainCollection",关联集合是"relatedCollection" var mongoClient = new MongoClient("mongodb://localhost:27017"); var database = mongoClient.GetDatabase("yourDatabaseName"); var mainCollection = database.GetCollection<BsonDocument>("mainCollection"); // 把你的聚合查询转换成BsonDocument数组 var pipeline = new[] { new BsonDocument("$match", new BsonDocument("status", "active")), // 你的$match条件 new BsonDocument("$lookup", new BsonDocument { { "from", "relatedCollection" }, { "localField", "relatedId" }, { "foreignField", "_id" }, { "as", "relatedData" } }), // 你的$lookup关联 new BsonDocument("$project", new BsonDocument { { "title", 1 }, { "relatedData", 1 }, { "_id", 0 } }), // 你的$project字段筛选 new BsonDocument("$sort", new BsonDocument("title", 1)) // 你的$sort排序 }; // 执行聚合查询,获取结果 var result = await mainCollection.Aggregate<BsonDocument>(pipeline).ToListAsync(); // 如果你的结果有对应的实体类,可以替换BsonDocument为你的实体类型 // var result = await mainCollection.Aggregate<YourEntity>(pipeline).ToListAsync();
方式二:使用LINQ构建聚合查询(类型安全)
如果你更倾向于用LINQ来写,MongoDB C#驱动提供了完整的LINQ支持,对应各个聚合阶段:
首先假设你有两个实体类和结果DTO:
public class MainEntity { public ObjectId Id { get; set; } public string Title { get; set; } public ObjectId RelatedId { get; set; } public string Status { get; set; } // 其他字段... public List<RelatedEntity> RelatedData { get; set; } } public class RelatedEntity { public ObjectId Id { get; set; } public string Name { get; set; } // 其他字段... } // 用于接收聚合结果的DTO public class AggregatedResult { public string Title { get; set; } public List<RelatedEntity> RelatedData { get; set; } }
然后用LINQ构建聚合:
using MongoDB.Driver; using MongoDB.Driver.Linq; var mongoClient = new MongoClient("mongodb://localhost:27017"); var database = mongoClient.GetDatabase("yourDatabaseName"); var mainCollection = database.GetCollection<MainEntity>("mainCollection"); var relatedCollection = database.GetCollection<RelatedEntity>("relatedCollection"); var aggregatedQuery = mainCollection.Aggregate() // $match阶段:筛选状态为active的文档 .Match(m => m.Status == "active") // $lookup阶段:关联relatedCollection .Lookup( foreignCollection: relatedCollection, localField: m => m.RelatedId, foreignField: r => r.Id, @as: (MainEntity m) => m.RelatedData) // $project阶段:只保留需要的字段 .Project(m => new AggregatedResult { Title = m.Title, RelatedData = m.RelatedData }) // $sort阶段:按Title升序排序 .SortBy(r => r.Title); // 获取结果列表 var result = await aggregatedQuery.ToListAsync();
关键注意点:
- 确保你安装了最新版的
MongoDB.DriverNuGet包(目前稳定版是2.x系列),旧版本的驱动才会有QueryDocument和MongoCursor这些弃用类型。 - 如果你的聚合查询有更复杂的条件(比如嵌套文档、数组操作),
BsonDocument方式更灵活;LINQ方式则提供类型安全,减少拼写错误。 - 聚合结果可以直接映射到自定义实体类,不需要手动解析
BsonDocument,非常方便。
内容的提问来源于stack exchange,提问作者TomSelleck
相关产品推荐
相关产品推荐

