You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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.Driver NuGet包(目前稳定版是2.x系列),旧版本的驱动才会有QueryDocument和MongoCursor这些弃用类型。
  • 如果你的聚合查询有更复杂的条件(比如嵌套文档、数组操作),BsonDocument方式更灵活;LINQ方式则提供类型安全,减少拼写错误。
  • 聚合结果可以直接映射到自定义实体类,不需要手动解析BsonDocument,非常方便。

内容的提问来源于stack exchange,提问作者TomSelleck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:46:58