我不确切知道您的数据是什么样的,但这里有一个例子来说明我的意思。假设这是您存储在数据库中的数据。
/* 1 */
{
"_id" : ObjectId("59e272e74d8a2fe38b86187d"),
"name" : "data1",
"date" : ISODate("2017-11-07T00:00:00.000Z"),
"number" : 15
}
/* 2 */
{
"_id" : ObjectId("59e272e74d8a2fe38b86187f"),
"name" : "data2",
"date" : ISODate("2017-11-06T00:00:00.000Z"),
"number" : 19
}
/* 3 */
{
"_id" : ObjectId("59e272e74d8a2fe38b861881"),
"name" : "data3",
"date" : ISODate("2017-10-06T00:00:00.000Z"),
"number" : 20
}
/* 4 */
{
"_id" : ObjectId("59e272e74d8a2fe38b861883"),
"name" : "data4",
"date" : ISODate("2017-10-05T00:00:00.000Z"),
"number" : 65
}
我了解您希望在数月甚至数年内比较某些值。因此,您可以执行以下操作
db.getCollection('test').aggregate([
{
$match: {
// query on the fields with index
date: {$gte: ISODate("2017-10-05 00:00:00.000Z"),
$lte: ISODate("2017-11-07 00:00:00.000Z")}
}
},
{
// retrieve the month from each document
$project: {
_id: 1,
name: 1,
date: 1,
number: 1,
month: {$month: "$date"}
}
},
{
// group them by month and perform some accumulator operation
$group: {
_id: "$month",
name: {$addToSet: "$name"},
dateFrom: {$min: "$date"},
dateTo: {$max: "$date"},
number: {$sum: "$number"}
}
}
])
我建议您保存预先汇总的数据,而不是每月搜索 30 个文档,例如您每月只需搜索 1 个。而且您只需要聚合一次完整的数据,如果您存储了预聚合结果,那么您只需对传入的新数据运行预聚合。
这可能是您正在寻找的东西吗?
此外,如果您有索引并且您查询的字段有索引,那么这也会有所帮助。否则 MongoDB 必须扫描集合中的每个文档。