[英]How to check if key exists in BsonDocument or not using Mongodb C# driver?
[英]How to perform multiple projections and lookups as aggregate in MongoDB using BsonDocument C# .NET driver?
我無法通過 C# .NET 驅動程序使用聚合功能來執行多個投影和查找。
這里我需要使用 mongodb C# .NET 驅動程序復制查詢。
db.organizations.aggregate([
{
"$project": {
"_id": {
"$toString": "$_id"
},
"Name": "$Name",
"LastDateUploaded": "$LastDateUploaded",
"LastDateEvaluated": "$LastDateEvaluated",
"PriorityId": "$PriorityId"
}
},
{
"$lookup": {
"from": "workflows",
"localField": "_id",
"foreignField": "Data.OrganizationId",
"as": "RelatedWorkflows"
}
},
{
"$lookup": {
"from": "priorities",
"localField": "PriorityId",
"foreignField": "_id",
"as": "Priority"
}
},
{
"$unwind": "$Priority"
},
{
"$project": {
"Name": "$Name",
"WorkflowCounter": {
"$size": "$RelatedWorkflows"
},
"LastDateUploaded": "$LastDateUploaded",
"LastDateEvaluated": "$LastDateEvaluated",
"Priority": "$Priority.Value"
}
},
{
"$sort": {
"Priority": -1,
"WorkflowCounter": 1,
"LastDateUploaded": -1,
"LastDateEvaluated": -1
}
}
])
我試圖做這樣的事情:
public class Organization
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id {get; set;}
public string NPOId { get; set; }
public string Name { get; set; }
public string Address { get; set; }
[BsonRepresentation(BsonType.ObjectId)]
public string PriorityId { get; set; }
[BsonIgnoreIfDefault]
public Priority Priority { get; set; }
public string City { get; set; }
public string County { get; set; }
[MaxLength(2)]
public string State { get; set; }
[BsonRepresentation(BsonType.ObjectId)]
public string CountryId { get; set; }
[BsonIgnoreIfDefault]
public Country Country { get; set; }
[MaxLength(5)]
public string Zip { get; set; }
public string TaxCode { get; set; }
public string ParentTaxCode { get; set; }
[BsonRepresentation(BsonType.ObjectId)]
public string CharityTypeId { get; set; }
[BsonRepresentation(BsonType.ObjectId)]
public string PreferredExtractorId { get; set; }
[BsonIgnoreIfDefault]
public User PreferredExtractor{ get; set; }
[BsonIgnoreIfDefault]
public CharityType CharityType { get; set; }
public string URL { get; set; }
public decimal Revenue { get; set; }
public decimal Expenses { get; set; }
public decimal Assets { get; set; }
public decimal Excess { get; set; }
public string IRSType { get; set; }
public string ICPAScore { get; set; }
public string ICPBScore { get; set; }
public string[] DefaultRules { get; set; }
[BsonIgnore]
public long NumberOfWorkflows { get; set; }
public DateTime? LastDateUploaded { get; set; }
public DateTime? LastDateEvaluated { get; set; }
}
var organizations = db.GetCollection<Organization>("catalog.organizations");
var aggregation = organizations.Aggregate().Match(_ => true);
var projectionOne = new BsonDocument {
{ "$project", new BsonDocument { { "_id", new BsonDocument { { "$toString", "$_id" } } } } },
{ "Name", "$Name"},
{ "LastDateUploaded", "$LastDateUploaded" },
{ "LastDateEvaluated", "$LastDateEvaluated"},
{ "PriorityId", "$PriorityId"}
};
aggregation.Project(projectionOne);
aggregation.AppendStage<Organizations>(new BsonDocument {
{ "$lookup", new BsonDocument { { "from", "wcf.workflows" }, { "localField", "_id" }, { "foreignField", "Data.OrganizationId" }, { "as", "RelatedWorkflows" } } }
});
aggregation.AppendStage<Organizations>(new BsonDocument {
{ "$lookup", new BsonDocument { { "from", "catalog.priorities" }, { "localField", "PriorityId" }, { "foreignField", "_id" }, { "as", "Priority" } } }
});
aggregation.AppendStage<Organizations>(new BsonDocument {
{ "$unwind", "$Priority" }
});
aggregation.AppendStage<Organizations>(new BsonDocument {
{ "$project", new BsonDocument { { "Name", "$Name" }, { "WorkflowCounter", new BsonDocument { { "$size", "$RelatedWorkflows" } } } } },
{ "LastDateUploaded", "$LastDateUploaded" },
{ "LastDateEvaluated", "$LastDateEvaluated"},
{ "PriorityValue", "$Priority.Value"}
});
aggregation.AppendStage<Organizations>(new BsonDocument {
{ "$sort", new BsonDocument { { "Priority", 1 }, { "WorkflowCounter", 1 }, { "LastDateUploaded", -1 }, { "LastDateEvaluated", -1} } }
});
var organizationsList = await aggregation.ToListAsync();
但是這不起作用,例如我反轉了排序選項並且總是返回相同的值。 我試圖獲得 mongo 查詢的字符串表示,但我只得到
aggregate([{ "$match" : { } }])
並且不附加聚合定義。
我嘗試使用流暢的表示法來執行查找,但我需要使用 ObjectId 和字符串字段來執行查找,因此出於這個原因,我首先在 mongodb 端解析 ObjectId 以使用第一個投影進行字符串處理,似乎沒有等價於將 ObjectId 轉換為字符串以執行查找(又名連接)的流利符號。
這是查詢在 mongo shell 上正常工作的測試證明: https : //mongoplayground.net/p/dKT8uQHjHnd
我希望從 mongo playground 示例中生成的列表中獲取第一個文檔,但我總是獲取集合的第一個元素。
我結束了下一步:
var organizations = db.GetCollection<Organization>("catalog.organizations");
var projectionOne = new BsonDocument {
{ "$project", new BsonDocument {
{ "_id", new BsonDocument { { "$toString", "$_id" } } },
{ "Name", "$Name"},
{ "LastDateUploaded", "$LastDateUploaded" },
{ "LastDateEvaluated", "$LastDateEvaluated"},
{ "PriorityId", "$PriorityId"}
}
}
};
var lookupOne = new BsonDocument {
{ "$lookup", new BsonDocument { { "from", "wfc.workflows" }, { "localField", "_id" }, { "foreignField", "Data.OrganizationId" }, { "as", "RelatedWorkflows" } } }
};
var lookupTwo = new BsonDocument {
{ "$lookup", new BsonDocument { { "from", "catalog.priorities" }, { "localField", "PriorityId" }, { "foreignField", "_id" }, { "as", "Priority" } } }
};
var unwindTwo = new BsonDocument {
{ "$unwind", "$Priority" }
};
var projectionTwo = new BsonDocument {
{ "$project", new BsonDocument {
{ "Name", "$Name" },
{ "WorkflowCounter", new BsonDocument { { "$size", "$RelatedWorkflows" } } },
{ "LastDateUploaded", "$LastDateUploaded" },
{ "LastDateEvaluated", "$LastDateEvaluated"},
{ "PriorityValue", "$Priority.Value"}
}
}
};
var sort = new BsonDocument {
{ "$sort", new BsonDocument { { "PriorityValue", -1 }, { "WorkflowCounter", 1 }, { "LastDateUploaded", -1 }, { "LastDateEvaluated", -1} } }
};
var aggregation = organizations.Aggregate<OrganizationWithWorkflows>(new [] {projectionOne, lookupOne, lookupTwo, unwindTwo, projectionTwo, sort});
var organizationsList = await aggregation.ToListAsync();
我創建了這個類來獲取最后的投影結果:
[BsonIgnoreExtraElements]
public class OrganizationWithWorkflows
{
public string Id { get; set; }
public string Name { get; set; }
public long WorkflowCounter {get; set;}
public DateTime? LastDateUploaded { get; set; }
public DateTime? LastDateEvaluated { get; set; }
public int PriorityValue { get; set; }
}
我花了一段時間,但我終於在這里解決了我的挑戰,部分是使用 ObjectId 和字符串字段執行查找,應用從 ObjectId 到字符串的強制轉換,並在同一查詢中應用多個投影和多個查找。
請注意,字段 counter 是包含在結果數組RelatedWorkflows
中的元素的大小,但這也可以在 lookupOne 和分組后應用展開以使用表達式{ $sum ,1 }
但在在我的情況下,使用上述數組中的 $size 表達式就足夠了。
我希望這可以幫助所有那些在理解如何使用BsonDocuments
使用 MongoDB 聚合和 C# .NET 驅動程序時遇到一些麻煩的人,因為無法使用流暢的表示法創建此查詢,因為將 ObjectId 轉換為字符串並使用那個用於 lookupOne 的,也許我在最后一部分上錯了,所以如果你知道怎么做,相信我也會很高興學習它。
為了獲得我的解決方案,我從 Mikael Koskinen 找到了這篇很棒的帖子,並閱讀了 mongodb 文檔以使用表達式$toString
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.