日期之间的MongoDB C#驱动程序聚合返回空字段

Chr*_*ein 10 c# mongodb aggregation-framework mongodb-.net-driver

我正在使用mongodb的c#驱动程序,并希望对我正在创建的Web API使用聚合查询.对于我的聚合查询,我关注的是具有用户名,日期和步骤的配置文件类.我想创建一个查询,选择用户名并获取给定周的总步数,按总步数降序排列.我只想显示他们的用户名和他们的总步数.

当我尝试聚合查询时,我遇到了一些问题,我的某些字段将显示为null.所以,我认为我的查询结构不正确.

我有一个"配置文件"类,我目前用于我的数据.

[BsonIgnoreExtraElements]
[DataContract]
public class Profile 
{   
    [DataMember]
    public string Username { get; set; }

    [DataMember]
    public DateTime Date { get; set; }

    [DataMember]
    public uint? Steps { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我使用以下方法创建了一些测试数据,例如配置文件

//Test data
for (uint index = 1; index < 20; index++)
{      
    Profile aprofile = new Profile
    {   
        Username = string.Format("testuser{0}", index),
        Date = RandomDay(),
        Steps = (index + index + index)*2

    };
    AddProfile(aprofile);
}
Run Code Online (Sandbox Code Playgroud)

如果我运行代码几次并查询特定用户,我得到的数据如下:

[{"Username":"testuser1","Date":"2014-07-03T00:00:00Z","Steps":6},
{"Username":"testuser1","Date":"2014-07-07T05:00:00Z","Steps":6},
{"Username":"testuser1","Date":"2014-07-17T05:00:00Z","Steps":6},
{"Username":"testuser1","Date":"2014-07-18T05:00:00Z","Steps":6}]
Run Code Online (Sandbox Code Playgroud)

然后,我有几个静态方法来查找我的聚合查询的最早日期和最新日期.

//gets a datetime for the earlist date and time possible for the current week
public static DateTime GetStartOfCurrentWeek()
{
    int DaysToSubtract = (int)DateTime.Now.DayOfWeek;
    DateTime dt = DateTime.Now.Subtract(TimeSpan.FromDays(DaysToSubtract));
    return new DateTime(dt.Year, dt.Month, dt.Day, 0, 0, 0, 0);
}

//gets a datetime for the latest date and time possible for the current week
public static DateTime GetEndOfCurrentWeek()
{
    DateTime dt = GetStartOfCurrentWeek().AddDays(6);
    return new DateTime(dt.Year, dt.Month, dt.Day, 23, 59, 59, 999);
}
Run Code Online (Sandbox Code Playgroud)

我在聚合查询中的尝试如下.

//Here is my aggregation query to get all profiles within a given week, 
public IEnumerable<Profile> GetAllProfiles()
{
    DateTime StartofWeek = GetStartOfCurrentWeek();
    DateTime EndofWeek = GetEndOfCurrentWeek();


    var match = new BsonDocument 
                {{ "$match", new BsonDocument 
                     {{ "Date", new BsonDocument {
                            {"$gte", StartofWeek},
                            {"$lt", EndofWeek}
                      }}}
                }};

    var group = new BsonDocument
                {{"$group",
                    new BsonDocument
                    {{ "_id", new BsonDocument
                         {{"id", "$Username"},

                    }},
                         {"Steps",  new BsonDocument
                              {{"$sum", "$Steps"}}
                    }}
                }};


    var sort =  new BsonDocument
                {{"$sort", new BsonDocument
                    {{"Steps", -1}}

                }};    



    var pipeline = new[] {match, group, sort};      

    var args = new AggregateArgs { Pipeline = pipeline, OutputMode = AggregateOutputMode.Inline };

    // run the aggregation query and get a list of BsonDocuments
    IEnumerable<BsonDocument> documents = _profiles.Aggregate(args);
}
Run Code Online (Sandbox Code Playgroud)

但是,我得到的结果是将用户名显示为Null,将日期显示为null.

[{"Username":null,"Date":"0001-01-01T00:00:00","Steps":96},
{"Username":null,"Date":"0001-01-01T00:00:00","Steps":66},
{"Username":null,"Date":"0001-01-01T00:00:00","Steps":24}]
Run Code Online (Sandbox Code Playgroud)

我需要做什么来获取我的文档数组,以便显示用户名以及我拥有的总步骤(似乎有效).我不想在查询结果中使用日期.只是用户名及其周的总步数.

Mak*_*kin 1

我真的不明白为什么你需要用 Bson 查询你的 mongo。你确实有你的模特课程。您尝试执行的聚合将如下所示:

var result = collection.Aggregate()
    .Match(r => r.Date >= StartofWeek && r.Date < EndofWeek)
    .Group(r=>r.Username, r=> new {UserName = r.Key, Dates  = r.Select(d=>d.Date),  Steps = r.Sum(x=>x.Steps)})
    .ToList();
Run Code Online (Sandbox Code Playgroud)

请注意,您可以获得的不是一个日期,而是一组日期,因此我将其聚合为Dates.

原因是您看不到日期和用户名是因为您没有查询它,在您的组语句中我只看到步骤的总和。如果您确实想继续以这种方式查询,您应该将其添加到小组阶段,例如:

var group = new BsonDocument
             {
                    { "_id", new BsonDocument{{"id", "$Username"},
             }},
             {"Steps",  new BsonDocument{{"$sum", "$Steps"}}},
             { "Dates", new BsonDocument{{"$addToSet", "$Date"}} },
             { "Username", new BsonDocument{{"$first", "$Username"}} },
        };
Run Code Online (Sandbox Code Playgroud)

这样我就可以在生成的 BsonDocument 中看到用户名和日期。

但正如我已经说过的,这种查询 Mongo 的方式并不是 C# 中最好的方式