Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I compose a date range query in Mongodb's aggregation framework?

My goal is to perform a match and group based on date range using mongodb 2.2 and latest c# driver.

I'm having trouble creating a match query in the aggregation framework that uses datetimes. I dont know if my datatype is incorrect (the poco has a datetime and the object was utc at save) or if the query is incorrect, which is more likely.

//Here is the doc format that I'm querying:

  {
      "DateTime" : new Date("2/20/2013 17:29:03"),
      "DateTimeString" : "20130220", 
      "PurchaseAmount" : 1.91, 
      "ProductId" : "51293ac844da932e941fa2c4",
      "_id" : "20130220/51293ac844da932e941fa2c4"
    } 

//and here is the aggregation query i'm attempting

    var timeStamp = DateTime.UtcNow.AddDays(-20);
    var startDate = timeStamp.Date;
    var endDate = timeStamp.AddDays(1).Date;

 var match = new BsonDocument 
                { 
                    { 
                        "$match", 
                        new BsonDocument 
                            { 
                               { "ProductId" ,  "51293ac844da932e941fa2c4"} 
                            }
                    } 
                };
            var match2 = new BsonDocument 
                { 
                    { 
                        "$match", 
                        new BsonDocument 
                            {  
             ***              { "$gte" ,  new BsonDocument{{"DateTime", timeStamp}} } //,
             ***                 // { "$lt" ,  endDate}
                            }
                    } 
                };

            var group = new BsonDocument 
                { 
                    { "$group", 
                        new BsonDocument 
                            { 
                                { "_id",  new BsonDocument 
                                        { 
                                           { "ProductId" ,  "$ProductId"}
                                           ,{ "DateTime" ,  "$DateTime"  }
                                        }   

                                }, 
                                { 
                                    "AvgOrder", new BsonDocument 
                                                 { 
                                                     { "$avg", "$PurchaseAmount" } 
                                                 } 
                                } 
                            } 
                  } 
                };

  var pipeline = new[] { match, match2, group };
            var aggregateResult = dbSession.GetCollection<RecentOrders>().Aggregate(pipeline);

Please see the *. I want to provide specific time ranges and calculate the average orders for that customer over that interval (by minute, hour, or day ranges). I believe that I have it working except for the date range query portion (match2). I think the issue is the tricky combination of new BsonDocuments and the query. Thanks so much if you can help!

like image 800
user376456 Avatar asked Dec 03 '25 02:12

user376456


2 Answers

You've got things swapped around in match2. It should be like this instead:

var match2 = new BsonDocument 
    {{ "$match", new BsonDocument 
        {{ "DateTime", new BsonDocument {
            {"$gte", timeStamp},
            {"$lt", endDate}
        }}}
    }};
like image 88
JohnnyHK Avatar answered Dec 04 '25 14:12

JohnnyHK


another syntax without too many curly braces

var match2 = new BsonDocument()
    .Add("$match",
         new BsonDocument().Add("TimeStamp",
                                new BsonDocument().Add("$gte", timestamp)
                                                  .Add("$lte", end)));
like image 44
jack-london Avatar answered Dec 04 '25 15:12

jack-london



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!