Novkovski Stevo Bato
Novkovski Stevo Bato

Reputation: 1043

MongoDB aggregate groupby id is always null

I`m trying to aggregate my hour series by day but something is wrong with my code.

My class is:

public class Serie {  
    [BsonId]
    public ObjectId Id { get; set; }

    [BsonDateTimeOptions(Kind = DateTimeKind.Utc)]
    public DateTime Hour { get; set; }

    public ObjectId UserId { get; set; }
    public ObjectId AppId { get; set; }

    public AppHourSerieMetric Type { get; set; }

    public double Value { get; set; }
}

My aggregate method is :

var args = new AggregateArgs();

var pipeline = new[]
{
    new BsonDocument("$match",
        Query<AppHourSerieEntity>.EQ(c => c.UserId, user).ToBsonDocument()),
    new BsonDocument("$match",
        Query<AppHourSerieEntity>.EQ(c => c.Type, metric).ToBsonDocument()),
    new BsonDocument("$match",
        Query<AppHourSerieEntity>.GTE(c => c.Hour, from).ToBsonDocument()),
    new BsonDocument("$match",
        Query<AppHourSerieEntity>.LTE(c => c.Hour, to).ToBsonDocument()),
    new BsonDocument
    {
        {
            "$project",
            new BsonDocument
            {
                {"key", "$dateToString: { format: '%Y-%m-%d', date: '$Hour' }"},
                {"value", "$Value"}

            }
        }
    },

    new BsonDocument
    {
        {
            "$group", new BsonDocument
            {
                {"key", "$key"},
                {"Value", new BsonDocument {{"$sum", "$value"}}},
                {"Count", new BsonDocument {{"$sum", (double) 1}}}
            }
        }
    }
};

args.Pipeline = pipeline;
args.AllowDiskUse = true;

var aggregate = _repo.GetCollection().Aggregate(args);

While using this code, looks like "Value" and "Count" is ok but "_id" is always null. I don`t know why, but "project" works since "Value" value is as i expected.

I also tried this code:

var pipeline = new[]
{
    new BsonDocument("$match",
        Query<AppHourSerieEntity>.EQ(c => c.UserId, user).ToBsonDocument()),
    new BsonDocument("$match",
        Query<AppHourSerieEntity>.EQ(c => c.Type, metric).ToBsonDocument()),
    new BsonDocument("$match",
        Query<AppHourSerieEntity>.GTE(c => c.Hour, from).ToBsonDocument()),
    new BsonDocument("$match",
        Query<AppHourSerieEntity>.LTE(c => c.Hour, to).ToBsonDocument()),                  
    new BsonDocument
    {
        {
            "$group", new BsonDocument
            {
                {"_id", "{ month: { $month: '$Hour' }, day: { $dayOfMonth: '$Hour' }, year: { $year: '$Hour' } }"},
                {"Value", new BsonDocument {{"$sum", "$Value"}}},
                {"Count", new BsonDocument {{"$sum", (double) 1}}}
            }
        }
    }
};

but the returned result for "_id" is as i wrote it:

 {  
   "_id":"{ month: { $month: '$Hour' }, day: { $dayOfMonth: '$Hour' }, year: { $year: '$Hour' } }",
   "Value":16210.0,
   "Count":3.0
}

So looks like in both codes "Value" and "Count" is ok, but "_id" is wrong. Any tips?

Upvotes: 0

Views: 1333

Answers (1)

Blakes Seven
Blakes Seven

Reputation: 50406

Use BsonDocument and not strings in your _id for $group:

        new BsonDocument
        {
            {
                "$group", new BsonDocument
                {
                    {
                        "_id", 
                        new BsonDocument 
                          { 
                            { "month", new BsonDocument("$month", "$Hour") }, 
                            { "day", new BsonDocument("$dayOfMonth", "$Hour") }, 
                            { "year", new BsonDocument("$year", "$Hour") }
                          }
                    },
                    {"Value", new BsonDocument {{"$sum", "$Value"}}},
                    {"Count", new BsonDocument {{"$sum", (double) 1}}}
                }
            }
        }

Upvotes: 1

Related Questions