0

我目前正在通过添加一个我可以注入的 MongoDB 存储库而不是 MS SQL Server 存储库来向我的应用程序添加 MongoDB 支持。到目前为止,一切都很顺利,因为大多数查询都很简单并且数据库结构迁移得很好(这相当简单)。

我目前正在处理一些总结报告,这些报告使用 SQL Server 实现起来相对简单:

所以我有一张表(为了清楚起见进行了简化),说:

[  Runners  ]
[RunnerId int]
[DateRun DateTime]
[RaceTime float]

现在我想要一个摘要,其中包含所有跑步者的列表和他们最后一场比赛的时间。请注意,上表将为每个跑步者提供多个条目。

在 SQL 中,这可以通过以下方式实现:

SELECT r.runnerId, r.DateRun, r.RaceTime
FROM (
    SELECT runnerId, MAX(DateRun) AS lastRace
    FROM Runners GROUP BY runnerId
) AS x INNER JOIN runners AS r ON
    r.runnerId = x.runnerId AND 
    r.DateRun = x.lastRace

我正在使用官方的 C# 10gen 驱动程序。欢迎提示和指点。

4

1 回答 1

1

正如前面所有评论所指出的,这可以使用聚合框架来实现。我将 C# 留给你,但我将演示一个使用 Mongo shell 的简单示例。

从以下示例数据开始。

> db.runners.find()
{ "_id" : ObjectId("50b3ec3c9dc68d628bd11869"), "name" : "a", "d" : ISODate("2012-10-29T00:00:00Z"), "time" : 10.3 }
{ "_id" : ObjectId("50b3ec429dc68d628bd1186a"), "name" : "a", "d" : ISODate("2012-10-20T00:00:00Z"), "time" : 12.3 }
{ "_id" : ObjectId("50b3ec549dc68d628bd1186b"), "name" : "b", "d" : ISODate("2012-10-29T00:00:00Z"), "time" : 11.45 }
{ "_id" : ObjectId("50b3ec5a9dc68d628bd1186c"), "name" : "b", "d" : ISODate("2012-10-25T00:00:00Z"), "time" : 11 }
{ "_id" : ObjectId("50b3ec6a9dc68d628bd1186d"), "name" : "c", "d" : ISODate("2012-10-25T00:00:00Z"), "time" : 10.8 }
{ "_id" : ObjectId("50b3f1249dc68d628bd1186e"), "name" : "b", "d" : ISODate("2012-11-13T00:00:00Z"), "time" : 23.2 }

然后,以下聚合查询返回:

> db.runners.aggregate({$sort:{name:1,d:-1}},{$group:{_id:"$name",d:{$first:"$d"},time:{$first:"$time"}}})
{
    "result" : [
        {
            "_id" : "c",
            "d" : ISODate("2012-10-25T00:00:00Z"),
            "time" : 10.8
        },
        {
            "_id" : "b",
            "d" : ISODate("2012-11-13T00:00:00Z"),
            "time" : 23.2
        },
        {
            "_id" : "a",
            "d" : ISODate("2012-10-29T00:00:00Z"),
            "time" : 10.3
        }
    ],
    "ok" : 1
}

首先,$sort操作员按runners降序排序named因此每个跑步者姓名的第一个文档应该是每个跑步者最近的跑步日期。然后,$group操作员为每个跑步者提取第一个文档,以及该比赛的最近跑步日期和运行时间。

于 2012-11-26T22:52:58.623 回答