我希望有人能帮助:
我有MongoDB收集一个用户,它有一个名为报告的数组,其中包含具有id的对象。我可以检索ID,但我试图从另一个集合检索查找值,因此User.Reports.Id应该返回Reports集合中与该ID关联的值。这类似于Mongoose.
中的.populate函数。我已经尝试了许多解决方案,但似乎无法使其工作。从我的研究,似乎我应该使用aggregate().lookup(),但我还没有设法让它工作。
public class UserModel
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string? Id { get; set; }
//from azure active directory b2c
public string? ObjectIdentifier { get; set; }
public string? FirstName { get; set; }
public string? LastName { get; set; }
public string? DisplayName { get; set; }
public string? EmailAddress { get; set; }
public string? PhoneNumber { get; set; }
public List<BasicReportsModel> Reports { get; set; } = new();
}
public class BasicReportsModel
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string? Id { get; set; }
public BasicReportsModel()
{
}
public BasicReportsModel(ReportsModel report)
{
Id = report.Id;
}
}
private readonly IMongoCollection<UserModel> _users;
private readonly IMongoCollection<ReportsModel> _reports;
public MongoUserData(IDbConnection db)
{
_users = db.UserCollection;
_reports = db.ReportsCollection;
}
public async Task<UserModel> GetUserData(string id)
{
// this brings back the user model with the Reports array and objects. I need to bring back the documents related to the ID's in User.Reports.Id
var results = await _users.FindAsync(u => u.Id == id);
return results.FirstOrDefault();
}
有没有人能帮我找到一个解决办法或给我指个方向。
有了aggregate
和$lookup
,你就走上了正确的轨道。为了让它与c#驱动程序一起工作,你应该定义一个包含报告的模型类,例如:
public class UserWithReportsModel : UserModel
{
public IEnumerable<ReportsModel> Reports { get; set; }
}
你可以改变你的GetUserData
方法来执行一个$lookup
阶段的聚合:
public async Task<UserWithReportsModel> GetUserData(string id)
{
return await (_users.Aggregate()
.Match(x => x.Id == 1)
.Lookup(foreignCollection: _reports,
localField: x => x.ReportIds,
foreignField: x => x.Id,
@as: (UserWithReportsModel x) => x.Reports))
.FirstOrDefaultAsync();
}
上面的语句返回用户的所有数据以及报表的详细信息。