MongoDB:聚合框架$ group,用C#保存ObjectdID

时间:2014-11-20 09:53:18

标签: mongodb aggregation-framework

我有以下表格(简化)的文件集合:

{
  "_id" : ObjectId("546534507a28ab1c646c7a12"),
  "Name" : "DataPack1",
  "Properties" : {
    "Location" : "Berlin",
    "Event" : "FreePractice1",
    "Car" : "car_Otto",
    "Driver" : "Otto",
    "RunNumber" : 0,
    "LapNumber" : 0,
    "LapTime" : 18.545993426137603,
    "LapType" : "Out",
    "TimeStamp" : ISODate("2014-11-13T23:08:42.522Z")
  },
  ...
}

我现在想要使用某些字段对数据集进行分组(例如"位置","事件")并找到某个值的最小值,例如:单圈。这与相应的AF管道非常相配,包括匹配,组和项目阶段。 我的$ group阶段看起来像这样,例如:

var group = new BsonDocument
{ 
    { "$group", 
        new BsonDocument 
        { 
            { "_id", new BsonDocument 
               { 
                  { "Location","$Properties.Location" }, 
                  { "Event","$Properties.Event" } 
               } 
            }, 
            { "FastestLap", new BsonDocument 
               { 
                   { "$min", "$Properties.LapTime" } 
               } 
            } 
        } 
    } 
}; 

一切都很简单。现在困扰我的是我有时需要一些元信息来找到最小值的问题,比如说它出现在哪个圈数/运行数。所以基本上我需要保留文件(或它的ID),这是实际的最小值。 更一般的是,是否存在保留原始文档的机制,从而导致聚合结果?我知道我可以使用类似的东西:

{
   "original": {"$push: "$$ROOT"}
}

但这又会产生聚合函数中考虑的所有文档,而不仅仅是我感兴趣的文档。

有没有办法实现这一目标,还是我必须编写一些map-reduce功能,我现在还不熟悉?

1 个答案:

答案 0 :(得分:0)

解决此问题的一种方法是:

  • 按照Properties.LapTime
  • 的升序对所有记录进行排序
  • 基于字段的小组。
  • 现在,每组最快单圈时间的记录将排在最前面 因为所有记录都按排序顺序排列。
  • 因此$first:"$$ROOT"会为您提供最快Laptime的记录 遇到了。

本机mongo驱动程序中的代码如下所示。请根据需要转换语法。

db.collection.aggregate([
{$sort:{"Properties.LapTime":1}},
{$group:{"_id":{"location":"$Properties.Location","event":"$Properties.Event"},
         "FastestLap":{$first:"$Properties.LapTime"},
         "fastestLapDocument":{$first:"$$ROOT"}}},
{$project:{"_id":0,"FastestLap":1,"fastestLapDocument":1}}
],{allowDiskUse :true})