前言
最近在寫項(xiàng)目的時(shí)候遇到一個(gè)問題,使用mongodb記錄了用例的執(zhí)行結(jié)果,但是在時(shí)間的記錄上使用的是date格式,現(xiàn)在有一個(gè)需求,以天為單位,統(tǒng)計(jì)一下每天成功的用例和失敗的用例,說到統(tǒng)計(jì),肯定是要用到聚合查詢,但是如果以date格式的時(shí)間為group依據(jù),那么等同于沒有分組,因?yàn)樵谟涗浻美臅r(shí)間幾乎不可能同時(shí),今天查閱了一下相關(guān)文檔,可以使用mongodb的$dateToString命令來完成這個(gè)需求
問題來源
假如我們以如下的數(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"
}
我的預(yù)期結(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來分組,由于每個(gè)時(shí)間都不相同,所以這樣的聚合就相當(dāng)于沒有聚合
#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上的時(shí)間,誰和誰都不一樣,所以如果以$time為分組對(duì)象的話每個(gè)統(tǒng)計(jì)都是1。
問題的解決
在分組的時(shí)候有一個(gè)$dateToString指令,可以將日期格式的值轉(zhuǎn)化為字符串,比如這里因?yà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/ 查看,簡單介紹一個(gè)
{ $dateToString: {
date: dateExpression>,
format: formatString>,
timezone: tzExpression>,
onNull: expression>
} }
它需要四個(gè)參數(shù),只有date參數(shù)是必須的,指定數(shù)據(jù)來源,format是轉(zhuǎn)化的格式,timezone為時(shí)區(qū),onNull是如果日期值不存在時(shí)返回的值。
#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}
這個(gè)看起來還不錯(cuò),但是離我的目標(biāo)還差一點(diǎn),因?yàn)樗€沒有按照用例執(zhí)行結(jié)果進(jìn)行分組,再以天進(jìn)行倒序排列
#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}},
]
但是這個(gè)指令只能適用于單一月份,如果兩個(gè)月就會(huì)有交集,如7月6號(hào)和6月6號(hào)的會(huì)聚合到一起
上面得到的結(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)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
您可能感興趣的文章:- JAVA mongodb 聚合幾種查詢方式詳解
- MongoDB教程之聚合(count、distinct和group)
- Mongodb聚合函數(shù)count、distinct、group如何實(shí)現(xiàn)數(shù)據(jù)聚合操作
- MongoDB聚合功能淺析
- MongoDB入門教程之聚合和游標(biāo)操作介紹
- MongoDB聚合分組取第一條記錄的案例與實(shí)現(xiàn)方法
- mongodb聚合_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
- mongoDB中聚合函數(shù)java處理示例詳解