MongoDB——Aggregates(c#實現支援陣列欄位)
阿新 • • 發佈:2019-01-03
c#實現
新增如下引用:本文引用版本為:Version=2.2.4.26
using MongoDB.Bson;
using MongoDB.Driver;
構建聚合管道:要求能夠
- 返回指定條數記錄
- 針對過濾結果聚合
- 支援非陣列欄位
- 支援陣列欄位資料拆分
構建程式碼如下:
/// 構建聚合管道 /// </summary> /// <param name="filterJson">過濾條件</param> /// <param name="limit">限制返回條數</param> /// <param name="field">聚合欄位名稱</param> /// <param name="isArray"></param> /// <returns></returns> public PipelineDefinition<BsonDocument, BsonDocument> GetPipeLine(string filterJson, int limit, string field, bool isArray = true) { string pipeline3 = string.Format(" {{$group: {{_id:'${0}', count: {{$sum: 1}}}}}}", field); string pipeline4 = string.Format(" {{$limit: {0}}}", limit); var pipelines = new List<string> { pipeline3, pipeline4 }; if (!string.IsNullOrEmpty(filterJson)) { var pipeline2 = string.Format(" {{$match:{0}}}", filterJson); pipelines.Insert(0, pipeline2); } if (isArray) { var pipeline1 = string.Format(" {{$unwind:'${0}'}}", field); pipelines.Insert(0, pipeline1); }
根據構建管道執行聚合:
/// <summary> /// 獲得聚合結果 /// </summary> /// <param name="pipeline"></param> /// <returns></returns> public async Task<List<BsonDocument>> GetAggregate(PipelineDefinition<BsonDocument, BsonDocument> pipeline) { var aggs = await GetCollection().AggregateAsync(pipeline); return await aggs.ToListAsync(); }
返回的是文件列表
以上是兩個基礎方法,依據不同業務需求可以進行組合呼叫
業務需求:
支援對多欄位進行聚合,統一返回所有的聚合結果
每個欄位的聚合結果為聚合內容和總記錄個數
首先返回單個欄位聚合結果:
/// <summary> /// 獲得單個欄位的聚合結果 /// </summary> /// <param name="filterJson"></param> /// <param name="limit"></param> /// <param name="field"></param> /// <returns></returns> public async Task<Dictionary<string, int>> GetAggs(string filterJson, int limit, string field) { var access = new MongoAccessAuto(); var pipeline = access.GetPipeLine(filterJson, limit, field); List<BsonDocument> aggs; try { aggs = await access.GetAggregate(pipeline); } catch (Exception) { pipeline = access.GetPipeLine(filterJson, limit, field, false); aggs = await access.GetAggregate(pipeline); } //轉化返回聚合形式 var groups = aggs.ConvertAll(s => s.ToDictionary()); var tokens = new Dictionary<string, int>(); foreach (var group in groups) { var id = @group["_id"]?.ToString() ?? "null"; var records = Convert.ToInt32(group["count"].ToString()); tokens.Add(id, records); } return tokens; }
以上將聚合結果儲存在字典當中,並且支援對陣列欄位資料的拆分,使得陣列欄位內容被拆分為多條進行聚合統計
邏輯呼叫獲得業務需求結果:
//獲得聚合結果
var gc = new GroupCollection();
if (groupCondition?.GFields != null)
{
foreach (var field in groupCondition.GFields)
{
var tokens = await Provider.GetAggs(filterCondition?.ToString(), groupCondition.Top, field);
gc.Add(field, tokens);
}
response.Groups = gc;
}
其中最終存放聚合結果的形式為
public class GroupCollection : Dictionary<string, Dictionary<string, int>>
{ }
得到的結果展示為:
"groups": {
"s:datasourcename": {
"cnki": 30,
"網際網路g頁資源": 3,
"圖形庫": 8
},
"s:format": {
"gif": 4,
"bmp": 4,
"tif": 5,
"jpg": 5,
"xlsx": 4,
"pdf": 4,
"doc": 5,
"html": 3,
"png": 4,
"dataset": 3
},
"s:media": {
"null": 3,
"數字儲存": 38
},
"ep:o:organization": {
"中國礦物岩石地球": 2,
"中國地質大學(北京)": 9,
"中海研究中心": 4,
"中國科學院洋研究所": 1,
"長江學": 9,
"中國科研究所": 1,
"中國地大學(武漢)": 2,
"成都理學": 2,
"石油社": 3,
"中化石發有限公司": 8
},
"b:contributor": {
"冉江": 1,
"陳民": 1,
"王菊": 3,
"吳娟": 1,
"李峰": 1,
"耿威": 2,
"xiaofeng": 8,
"施生": 3,
"於維": 9,
"崔葉": 4
}
}