如何用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
相关产品推荐
相关产品推荐

