1. 程式人生 > >.NET 官方驅動MongoDB.Driver的聚合管道Aggregate用法(二)之操作符的用法示例及細節

.NET 官方驅動MongoDB.Driver的聚合管道Aggregate用法(二)之操作符的用法示例及細節

上一篇文章寫了如何去寫一個聚合管道的類以及例項化後的基本查詢實現。傳送門

本文筆者想記錄在具體實現按日期統計資料進行Aggregate時,在編寫查詢條件時的一些容易忽略的小細節(筆者自己忽略的和遇到的問題)進行記錄,以備後用,錯誤之處,請留言指正。

1.時間問題

             //ISODate的時間是UTC時間,所以做查詢的時候需要北京時間減去8小時,轉字串,在用ISODate處理成$match條件
            //普通查詢
            DateTime dtLimit = DateTime.Parse("2018-12-01 00:00:01");
            dtLimit= dtLimit.AddHours(-8);
            string utcDate = dtLimit.ToString("yyyy-MM-ddTHH:mm:ss");
            string pipelineJson1 = " {$project : {DTime : 1 ,AdvInf : 1}}";
            string pipelineJson2 = " { $match : { DTime : { $gte :ISODate('"+ utcDate + "') } } }";

            IList<IPipelineStageDefinition> stages = new List<IPipelineStageDefinition>();
            PipelineStageDefinition<BsonDocument, BsonDocument> stage1 =
                new JsonPipelineStageDefinition<BsonDocument, BsonDocument>(pipelineJson1);
            PipelineStageDefinition<BsonDocument, BsonDocument> stage2=
                new JsonPipelineStageDefinition<BsonDocument, BsonDocument>(pipelineJson2);

            stages.Add(stage1);
            stages.Add(stage2);
    
            PipelineDefinition<BsonDocument, BsonDocument> pipeline = new PipelineStagePipelineDefinition<BsonDocument, BsonDocument>(stages);
            MongoHelper operatDb = new MongoHelper();
            MongoDBAggregate mongo = new MongoDBAggregate("mongodb://192.168.5.99:101");

            var result = mongo.GetAggregate("EHQQDZ309", "201812", pipeline).ToList();

時間轉換:$match中的時間條件比較,必須將時間使用ISODate()進行處理。且ISODate函式的時間字串,如果涉及時分秒,其字串引數格式必須是0000-00-00T00:00:00。

時區問題:大家知道MongoDB中,預設使用的UTC時間,而我們日常開始的時間是北京時間,領先UTC 8個小時,即UTC時間=北京時間+8小時。如果我們將時間作為查詢條件,那麼需要將目標的時間(北京時間)減去8個小時,再轉換處理後,輸入到$match操作符中。舉例講,就是如果 我要查詢2018-12-1 00:00:01時開始至今的資料,假設該時間點存在一條記錄,那麼其實這個其實記錄在MongoDB中儲存的時間戳應該是2018-11-30 16:00:01。

所以我們需要將2018-12-1 00:00:01的變數減去8小時,生成字串“2018-11-30T16:00:01”,當輸入到$match操作附中的ISODate函式實際轉換時,就將其轉換成了“2018-10-31T16:00:05.000Z”,注意後面的Z,表示UTC時間,那查詢的條件就是UTC時間大於“2018-10-31T16:00:05.000Z”的記錄,即大於北京時間“2018-12-1 00:00:01”的記錄。

補充:UTC是協調世界時(Universal Time Coordinated)英文縮寫,是由國際無線電諮詢委員會規定和推薦,並由國際時間局(BIH)負責保持的以秒為基礎的時間標度。UTC相當於本初子午線(即經度0度)上的平均太陽時,過去曾用格林威治平均時(GMT)來表示.北京時間比UTC時間早8小時,以1999年1月1日0000UTC為例,UTC時間是零點,北京時間為1999年1月1日早上8點整。

 

2.$Sort的用法

①統計12月份每天資料儲存的數量

 //資料統計
 string pipelineJson1= " { $match : { DTime : { $gte :ISODate('2018-10-04T02:20:12') } } }";
 string pipelineJson2 = "{$group:{_id:{month:{$month:'$DTime'},day:{$dayOfMonth:'$DTime'}}, count: {$sum:1},total:{$sum:'xStepCounter'}}}";
 string pipelineJson3 = " {$sort:{_id:1}}";  //升序

筆者想按日期排序,因為這個Collection(表)中只有12月的資料,所以排序的程式碼謝偉 string pipelineJson3 = " {$sort:{day:1}}",執行不會報錯,結果順序並沒有按照日期排列。

改為上面程式碼段中的 string pipelineJson3 = " {$sort:{_id:1}}"  ,按_id升序排列,結果正確。