【问题标题】:MongoDB: aggregation framework $group, preserve ObjectdID with C#MongoDB:聚合框架 $group,用 C# 保留 ObjectdID
【发布时间】:2014-11-20 18:31:02
【问题描述】:

我有以下形式的文档(简体):

{
  "_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 功能?

【问题讨论】:

    标签: mongodb aggregation-framework


    【解决方案1】:

    解决这个问题的一种方法是:

    • 按照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})
    

    【讨论】:

    • 这是解决这个问题的好方法(类似于 SQL 中的解决方案),但我有点担心性能。在您的“全局排序”解决方案中,我可能必须先对数十万个文档进行排序,而不是先对它们进行分组然后再排序。无论如何,谢谢,我会使用这个解决方案,直到找到更好的解决方案;)
    • 如果您在 Properties.LapTime 上建立索引,那么排序是索引的一部分,您不会因对大量文档进行排序而受到巨大损失。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-11
    • 2013-07-20
    • 2012-09-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多