您的位置:首页 > 数据库 > Mongodb

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

2016-10-14 14:21 274 查看
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
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐