这是我到目前为止在聚合查询:
上尝试的内容db.getCollection('storage').aggregate([
{
"$match": {
"user_id": 2
}
},
{
"$project": {
"formattedDate": {
"$dateToString": { "format": "%Y-%m", "date": "$created_on" }
},
"size": "$size"
}
},
{ "$group": {
"_id" : "$formattedDate",
"size" : { "$sum": "$size" }
} }
])
这是结果:
/* 1 */
{
"_id" : "2018-02",
"size" : NumberLong(10860595386)
}
/* 2 */
{
"_id" : "2017-12",
"size" : NumberLong(524288)
}
/* 3 */
{
"_id" : "2018-01",
"size" : NumberLong(21587971)
}
这是文档结构:
{
"_id" : ObjectId("5a59efedd006b9036159e708"),
"user_id" : NumberLong(2),
"is_transferred" : false,
"is_active" : false,
"process_id" : NumberLong(0),
"ratio" : 0.000125759169459343,
"type_id" : 201,
"size" : NumberLong(1687911),
"is_processed" : false,
"created_on" : ISODate("2018-01-13T11:39:25.000Z"),
"processed_on" : ISODate("1970-01-01T00:00:00.000Z")
}
最后,解释结果:
/* 1 */
{
"stages" : [
{
"$cursor" : {
"query" : {
"user_id" : 2.0
},
"fields" : {
"created_on" : 1,
"size" : 1,
"_id" : 1
},
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "data.storage",
"indexFilterSet" : false,
"parsedQuery" : {
"user_id" : {
"$eq" : 2.0
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"user_id" : 1
},
"indexName" : "user_id",
"isMultiKey" : false,
"multiKeyPaths" : {
"user_id" : []
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"user_id" : [
"[2.0, 2.0]"
]
}
}
},
"rejectedPlans" : []
}
}
},
{
"$project" : {
"_id" : true,
"formattedDate" : {
"$dateToString" : {
"format" : "%Y-%m",
"date" : "$created_on"
}
},
"size" : "$size"
}
},
{
"$group" : {
"_id" : "$formattedDate",
"size" : {
"$sum" : "$size"
}
}
}
],
"ok" : 1.0
}
问题:
我可以在0,002sec
中几乎立即导航并获得所有结果。但是,当我指定user_id并通过每个月的分组对它们求和时,我的结果介于0,300s到0,560s之间。我在一个请求中执行类似的任务,并且完成时间超过一秒钟。
到目前为止我尝试了什么:
$match
个条件。但是,这更糟糕。此系列目前有近200,000份文件,其中约有150,000份属于user_id = 2
如何最小化此查询的响应时间?
注意:使用了MongoDB 3.4.10。
答案 0 :(得分:0)
Pratha,
尝试在“created_on”和“size”字段上添加sort作为聚合管道中的第一个阶段。
db.getCollection('storage').aggregate([
{
"$sort": {
"created_on": 1, "size": 1
}
}, ....
在此之前,添加复合键索引: 。db.getCollection( '存储装置')的createIndex({created_on:1,尺寸:1})
如果您在$ group阶段之前对数据进行排序,则会提高总计积累的效率。
关于排序聚合阶段的注意事项:
$ sort阶段的RAM限制为100兆字节。默认情况下,如果阶段超出此限制,$ sort将产生错误。要允许处理大型数据集,请将allowDiskUse选项设置为true以启用$ sort操作以写入临时文件。
P.S
通过userID摆脱匹配阶段以测试性能,或者也将userID添加到复合键。