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
}
}
添加如下引用:本文引用版本为: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
}
}
相关文章推荐
- [转]比较高效地实现从两个不同数组中提取相同部分组成新的数组(只支持Int类型) [C#]
- 使文件下载的自定义连接支持 FlashGet 的断点续传多线程链接下载! C#/ASP.Net 实现!
- .Net/C#: 实现支持断点续传多线程下载的 Http Web 客户端工具类 (C# DIY HttpWebClient)
- c#里如何实现控件数组
- .Net/C#: 实现支持断点续传多线程下载的 Http Web 客户端工具类
- /* .Net/C#: 实现支持断点续传多线程下载的 Http Web 客户端工具类【转】
- 数据结构与算法(C#实现)系列---二叉堆(数组实现)
- c#实现在一个表中有一个Url字段,查每条记录是否在一个文件夹下.如在保留此记录,不在将这个记录删除
- /* .Net/C#: 实现支持断点续传多线程下载的 Http Web 客户端工具类【转】
- C#: 实现支持断点续传多线程下载的
- C#对SQL2000TEXT字段存储的实现(使用存储过程)
- 使文件下载的自定义连接支持 FlashGet 的断点续传多线程链接下载! C#/ASP.Net 实现
- .Net/C#: 实现支持断点续传多线程下载的 Http Web 客户端工具类 (第2版) (C# DIY HttpWebClient) 收藏
- C#实现数组的排序
- 用C#实现简单的控件数组
- .Net/C#: 实现支持断点续传多线程下载的 Http Web 客户端工具类 (第2版) (C# DIY HttpWebClient)
- .Net/C#: 实现支持断点续传多线程下载的 Http Web 客户端工具类 (第2版) (C# DIY HttpWebClient)
- C# 没有动态数组,实现动态数组 && local copy(dll)
- 使文件下载的自定义连接支持 FlashGet 的断点续传多线程链接下载! C#/ASP.Net 实现!
- 【转载】c#实现控件数组