MongoDB——Aggregates(c#实现支持数组字段)

来源:互联网 发布:天涯与知乎 编辑:程序博客网 时间:2024/05/29 02:32

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      }    }





0 0
原创粉丝点击