C# 如何使用MongoDB';s Map在减少影响的同时减少…尽可能保持数据存储不可知?
我提出这个问题是因为它与C#解决方案有关,然而,我在RoR解决方案中也面临同样的困境,只是选择最大限度地使用Map Reduce,放弃了所有抽象数据存储的希望 MongoDB Map Reduce似乎是执行数据透视和其他报告查询的方法。另一种方法是将逻辑移动到应用层,这是典型的文档存储库方式,如典型的EntityFramework(EF)人员所鼓励的 没有深入讨论每种方法的相对优势,数据存储中的数据量被证明太大,无法将其全部提取到应用层 下面的代码是一个概念证明(POC),它产生了结果,但回避了我在这里要问的问题:有没有一种方法可以减少在C#(任何.NET)解决方案中使用Map reduce的影响 始终使用的数据模型:C# 如何使用MongoDB';s Map在减少影响的同时减少…尽可能保持数据存储不可知?,c#,mongodb,entity,inversion-of-control,C#,Mongodb,Entity,Inversion Of Control,我提出这个问题是因为它与C#解决方案有关,然而,我在RoR解决方案中也面临同样的困境,只是选择最大限度地使用Map Reduce,放弃了所有抽象数据存储的希望 MongoDB Map Reduce似乎是执行数据透视和其他报告查询的方法。另一种方法是将逻辑移动到应用层,这是典型的文档存储库方式,如典型的EntityFramework(EF)人员所鼓励的 没有深入讨论每种方法的相对优势,数据存储中的数据量被证明太大,无法将其全部提取到应用层 下面的代码是一个概念证明(POC),它产生了结果,但回避了
public class Call
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public DateTime? StartTime { get; set; }
public DateTime? EndTime { get; set; }
public Agent Agent { get; set; }
public Caller Caller { get; set; }
}
public class Agent : Person
{
public DateTime JoinedCompany { get; set; }
}
public class Caller : Person
{
}
Map Reduce POC中使用的数据模型:
public class AgentCallSummary
{
public ObjectId _id;
public AgentCallAggregateValues value;
public class AgentCallAggregateValues
{
public int count;
public int totalTimeOnCall;
}
}
下面的代码依赖于CreateCollection()和扩展方法Dump(这个T,string),它们用于抽象地表示可以从任何文档存储中获取文档集合,并且可以转储任何文档(如LINQPad提供的):
private void演示MapReduce()
{
var calls=CreateCollectionCall();
calls.Count().Dump(“调用计数”);
常量字符串映射JavaScript=
@“职能(){
var call=this;
/*应获取averageCallTime,此处简化,averageCallTime用作正在进行的调用的timeOnCall*/
var averageCallTime=15.0;
var calculateTotalTimeOnCall=函数(开始时间、结束时间){
如果((!endTime)|(!startTime)){
返回平均调用时间;
}
var diffMs=结束时间-开始时间;
返回(diffMs/1000)*60;
};
emit(call.Agent.\u id,{count:1,totalTimeOnCall:1});
}";
常量字符串reduceJavascript=
@“功能(键、值){
var result={count:0,totalTimeOnCall:0};
values.forEach(函数(值){
result.count+=value.count;
result.totalTimeOnCall+=value.totalTimeOnCall;
});
返回结果;
}";
var mapReduceResult=calls.MapReduce(mapJavascript、reduceJavascript、MapReduceOptions.SetOutput(MapReduceOutput.Inline));
foreach(mapReduceResult.GetInlineResultsAs()中的变量项)
{
item.Dump();
}
}
我不明白你在找什么。C#与您使用MapReduce有什么关系?谢谢。该公司的软件开发实践要求保持数据存储的不可知性,即他们更喜欢EntityFramework而不是direct ADO.NET。当MongoDB被引入时,该公司只使用C#.Find()的10代驱动程序和各种查询方法(如FindOne())来满足这一目标。我理解不依赖数据存储的愿望,但强制将比必需的更大的数据集从MongoDB运送到应用层对我来说没有意义。我希望减少使用MongoDB的Map reduce的影响,因为它是由10代C#驱动程序公开的。但我不明白你所说的“减少影响”是什么意思?如果可以在DB服务器上完成,那么就完全可以避免将大量数据发送到中间层进行处理,因此很难看到您可以做的比您已经做的更多。这很公平。通过“减少影响”,我希望使用Map reduce或类似的方法,即MongoDB聚合框架,该框架用于数据存储无关的解决方案中。我完全愿意举手说,“我会考虑速度而不是可移植性。”我觉得这是我的尽职调查。您是否尝试过使用聚合框架的功能(并了解其当前的局限性)?
private void DemostrateMapReduce()
{
var calls = CreateCollectionCall<Call>();
calls.Count().Dump("Call Count");
const string mapJavascript =
@"function(){
var call = this;
/* averageCallTime should be fetched, simplified here, averageCallTime is used as the timeOnCall for calls that are in progress */
var averageCallTime = 15.0;
var calculateTotalTimeOnCall = function(startTime, endTime) {
if ((!endTime) || (!startTime)) {
return averageCallTime;
}
var diffMs = endTime - startTime;
return (diffMs / 1000) * 60;
};
emit(call.Agent._id, { count: 1, totalTimeOnCall: 1 });
}";
const string reduceJavascript =
@"function(key, values) {
var result = { count: 0, totalTimeOnCall: 0 };
values.forEach(function(value) {
result.count += value.count;
result.totalTimeOnCall += value.totalTimeOnCall;
});
return result;
}";
var mapReduceResult = calls.MapReduce(mapJavascript, reduceJavascript, MapReduceOptions.SetOutput(MapReduceOutput.Inline));
foreach (var item in mapReduceResult.GetInlineResultsAs<AgentCallSummary>())
{
item.Dump();
}
}