1. 程式人生 > >MongoDB——Aggregates(c#實現支援陣列欄位)

MongoDB——Aggregates(c#實現支援陣列欄位)

c#實現

新增如下引用:本文引用版本為:Version=2.2.4.26

using MongoDB.Bson;
using MongoDB.Driver;

構建聚合管道:要求能夠

  1. 返回指定條數記錄
  2. 針對過濾結果聚合
  3. 支援非陣列欄位
  4. 支援陣列欄位資料拆分

構建程式碼如下:

        /// 構建聚合管道
        /// </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
      }
    }