前言
最近在寫項目的時候遇到一個問題,使用mongodb記錄了用例的執(zhí)行結(jié)果,但是在時間的記錄上使用的是date格式,現(xiàn)在有一個需求,以天為單位,統(tǒng)計一下每天成功的用例和失敗的用例,說到統(tǒng)計,肯定是要用到聚合查詢,但是如果以date格式的時間為group依據(jù),那么等同于沒有分組,因為在記錄用例的時間幾乎不可能同時,今天查閱了一下相關(guān)文檔,可以使用mongodb的$dateToString命令來完成這個需求
問題來源
假如我們以如下的數(shù)據(jù)
/* 1 */
{
"_id" : ObjectId("5d24c09651a456efbc231669"),
"time" : ISODate("2019-07-08T10:12:35.125Z"),
"result" : "Pass"
}
/* 2 */
{
"_id" : ObjectId("5d24c09e51a456efbc23166a"),
"time" : ISODate("2019-07-08T10:12:36.125Z"),
"result" : "Pass"
}
...
...
/* 10 */
{
"_id" : ObjectId("5d24c0d851a456efbc231672"),
"time" : ISODate("2019-07-06T10:10:52.125Z"),
"result" : "Pass"
}
/* 11 */
{
"_id" : ObjectId("5d24c0e751a456efbc231673"),
"time" : ISODate("2019-07-06T10:10:52.125Z"),
"result" : "Fail"
}
我的預期結(jié)果是
{'_id': '2019-07-06', 'Pass': 1}
{'_id': '2019-07-06', 'Fail': 2}
{'_id': '2019-07-07', 'Pass': 2}
{'_id': '2019-07-07', 'Fail': 1}
{'_id': '2019-07-08', 'Pass': 2}
{'_id': '2019-07-08', 'Fail': 3}
如果按照以前的聚合方式,通過$time來分組,由于每個時間都不相同,所以這樣的聚合就相當于沒有聚合
#coding:utf-8
from pymongo import MongoClient
client = MongoClient(host=['%s:%s'%("127.0.0.1",27017)])
G_mongo = client['test']
pipeline = [
{'$group': {'_id': '$time', 'count': {'$sum': 1}}},
]
for i in G_mongo['test'].aggregate(pipeline):
print(i)
得到的結(jié)果
{'_id': datetime.datetime(2019, 7, 6, 10, 10, 32, 125000), 'count': 1}
{'_id': datetime.datetime(2019, 7, 7, 10, 10, 32, 125000), 'count': 1}
{'_id': datetime.datetime(2019, 7, 8, 10, 11, 22, 125000), 'count': 1}
{'_id': datetime.datetime(2019, 7, 6, 10, 10, 52, 125000), 'count': 1}
{'_id': datetime.datetime(2019, 7, 8, 10, 11, 32, 125000), 'count': 1}
{'_id': datetime.datetime(2019, 7, 8, 10, 12, 32, 125000), 'count': 1}
{'_id': datetime.datetime(2019, 7, 7, 10, 11, 22, 125000), 'count': 1}
{'_id': datetime.datetime(2019, 7, 8, 10, 12, 36, 125000), 'count': 1}
{'_id': datetime.datetime(2019, 7, 8, 10, 12, 35, 125000), 'count': 1}
{'_id': datetime.datetime(2019, 7, 7, 10, 10, 22, 125000), 'count': 1}
可以看到,由于$time上的時間,誰和誰都不一樣,所以如果以$time為分組對象的話每個統(tǒng)計都是1。
問題的解決
在分組的時候有一個$dateToString指令,可以將日期格式的值轉(zhuǎn)化為字符串,比如這里因為需求是要以天為單位,所以我將其轉(zhuǎn)為
%Y-%m-%d的字符串格式,具體的$grouop如下
{'$group': {'_id': {"$dateToString":{'format':'%Y-%m-%d','date':'$time'}}, 'count': {'$sum': 1}}}
$dateToString的說明文檔可以訪問https://docs.mongodb.com/manual/reference/operator/aggregation/dateToString/ 查看,簡單介紹一個
{ $dateToString: {
date: dateExpression>,
format: formatString>,
timezone: tzExpression>,
onNull: expression>
} }
它需要四個參數(shù),只有date參數(shù)是必須的,指定數(shù)據(jù)來源,format是轉(zhuǎn)化的格式,timezone為時區(qū),onNull是如果日期值不存在時返回的值。
#coding:utf-8
from pymongo import MongoClient
client = MongoClient(host=['%s:%s'%("127.0.0.1",27017)])
G_mongo = client['test']
pipeline = [
# {'$group': {'_id': '$time', 'count': {'$sum': 1}}},
{'$group': {'_id': {"$dateToString":{'format':'%Y-%m-%d','date':'$time'}}, 'count': {'$sum': 1}}}
]
for i in G_mongo['test'].aggregate(pipeline):
print(i)
上面代碼執(zhí)行的結(jié)果如下
{'_id': '2019-07-06', 'count': 2}
{'_id': '2019-07-07', 'count': 3}
{'_id': '2019-07-08', 'count': 5}
這個看起來還不錯,但是離我的目標還差一點,因為它還沒有按照用例執(zhí)行結(jié)果進行分組,再以天進行倒序排列
#coding:utf-8
from pymongo import MongoClient
client = MongoClient(host=['%s:%s'%("127.0.0.1",27017)])
G_mongo = client['test']
pipeline = [
# {'$group': {'_id': '$time', 'count': {'$sum': 1}}},
{'$group': {'_id': {'date':{"$dateToString":{'format':'%Y-%m-%d','date':'$time'}},'result':'$result'}, 'count': {'$sum': 1}}},
{'$sort':{"_id.date":-1}}
]
for i in G_mongo['test'].aggregate(pipeline):
print(i)
得到的結(jié)果如下
{'_id': {'date': '2019-07-08', 'result': 'Fail'}, 'count': 3}
{'_id': {'date': '2019-07-08', 'result': 'Pass'}, 'count': 2}
{'_id': {'date': '2019-07-07', 'result': 'Pass'}, 'count': 2}
{'_id': {'date': '2019-07-07', 'result': 'Fail'}, 'count': 1}
{'_id': {'date': '2019-07-06', 'result': 'Fail'}, 'count': 1}
{'_id': {'date': '2019-07-06', 'result': 'Pass'}, 'count': 2}
查看文檔,除了使用$dateToString指令還可以使用$dayOfMonth指令
pipeline = [
{'$group': {'_id': {'date':{"$dayOfMonth":{'date':'$time'}},'result':'$result'}, 'count': {'$sum': 1}}},
{'$sort':{"_id.date":-1}},
]
但是這個指令只能適用于單一月份,如果兩個月就會有交集,如7月6號和6月6號的會聚合到一起
上面得到的結(jié)果是
{'_id': {'date': 8, 'result': 'Fail'}, 'count': 3}
{'_id': {'date': 8, 'result': 'Pass'}, 'count': 2}
{'_id': {'date': 7, 'result': 'Pass'}, 'count': 2}
{'_id': {'date': 7, 'result': 'Fail'}, 'count': 1}
{'_id': {'date': 6, 'result': 'Pass'}, 'count': 2}
{'_id': {'date': 6, 'result': 'Fail'}, 'count': 1}
所以需要根據(jù)需求靈活的使用各種指令。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。
您可能感興趣的文章:- JAVA mongodb 聚合幾種查詢方式詳解
- MongoDB教程之聚合(count、distinct和group)
- Mongodb聚合函數(shù)count、distinct、group如何實現(xiàn)數(shù)據(jù)聚合操作
- MongoDB聚合功能淺析
- MongoDB入門教程之聚合和游標操作介紹
- MongoDB聚合分組取第一條記錄的案例與實現(xiàn)方法
- mongodb聚合_動力節(jié)點Java學院整理
- mongoDB中聚合函數(shù)java處理示例詳解