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

如何用MongoDB C# Driver按关联集合属性排序?

问题解答

这个需求完全可行,以下是用MongoDB C# Driver实现对应聚合逻辑的具体方案:

1. 定义对应集合的实体类(可选,强类型场景使用)

如果采用强类型操作,先定义与集合结构匹配的实体:

// CaseData集合实体
public class CaseData
{
    public string CaseId { get; set; }
    public CaseType Type { get; set; }
    public List<CaseUser> Users { get; set; }
    // 其他业务属性...
}

public class CaseType
{
    public string TypeId { get; set; }
}

public class CaseUser
{
    public string UserId { get; set; }
    public string UserType { get; set; }
    // 其他用户关联属性...
}

// Users集合实体
public class User
{
    public string UserId { get; set; }
    public UserData Data { get; set; }
}

public class UserData
{
    public UserProperty Property { get; set; }
}

public class UserProperty
{
    public bool SomeSortableProperty { get; set; }
}

// 聚合结果接收类(新增关联字段caseUser)
public class AggregateCaseResult : CaseData
{
    public List<User> CaseUser { get; set; }
}

2. 强类型聚合实现

对应原生聚合的$match、$lookup、$sort三个阶段:

using MongoDB.Driver;

// 初始化集合实例
var mongoClient = new MongoClient("your-connection-string");
var database = mongoClient.GetDatabase("your-db-name");
var caseCollection = database.GetCollection<CaseData>("cases");

// 构建聚合管道
var aggregateQuery = caseCollection.Aggregate()
    // 过滤条件:匹配指定typeId,且users数组存在且长度为1
    .Match(c => c.Type.TypeId == "someUniqueTypeId" && c.Users != null && c.Users.Count == 1)
    // 关联users集合,将匹配结果存入caseUser字段
    .Lookup<User, CaseData, AggregateCaseResult>(
        foreignCollection: database.GetCollection<User>("users"),
        localField: c => c.Users.Select(u => u.UserId),
        foreignField: u => u.UserId,
        @as: r => r.CaseUser
    )
    // 按关联用户的someSortableProperty倒序排序
    .SortByDescending(r => r.CaseUser[0].Data.Property.SomeSortableProperty);

// 执行查询获取结果
var results = await aggregateQuery.ToListAsync();

3. 弱类型(BsonDocument)聚合实现

如果不需要强类型,直接用BsonDocument构建管道更灵活:

var pipeline = new BsonDocument[]
{
    new BsonDocument("$match", 
        new BsonDocument
        {
            { "type.typeId", "someUniqueTypeId" },
            { "users", new BsonDocument("$exists", true) { { "$size", 1 } } }
        }
    ),
    new BsonDocument("$lookup", 
        new BsonDocument
        {
            { "from", "users" },
            { "localField", "users.userId" },
            { "foreignField", "userId" },
            { "as", "caseUser" }
        }
    ),
    new BsonDocument("$sort", 
        new BsonDocument("caseUser.data.property.someSortableProperty", -1)
    )
};

var results = await caseCollection.Aggregate<BsonDocument>(pipeline).ToListAsync();

关键说明

  • 因为前置$match已经过滤了users长度为1的文档,所以$lookup返回的caseUser数组必然只有一个元素,排序时直接取caseUser[0]即可。
  • 强类型实现中,Lookup方法需要指定三个泛型参数:源集合实体、关联集合实体、聚合结果实体(包含新增的关联字段)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 05:40:32