关于时间
在pipeline中查询时间一般使用
{'$match': {'component.0.start_date': {'$gt': ISODate("2022-01-01T00:00:00Z")}}}
性能优化
聚合管理有100M的RAM限制,如果数据信过大,可以设置allowDiskUse:true,但性能会下降很多。
sort和group的数据无法同时进行,是全集加工方法。
$sort优化
- 使用索引进行排序,如果无前期unwind(展开)、group或project阶段,建议将sort放在开头。
- 将sort直接放limit后使用时,会同时执行,以提升速度。
- 减少需sort的记录。
$group优化,包含count,sortByCount,facet
- 避免不必要的的分组。
- 仅累积 totals, counts和汇总数据。
避免因处理数组元素而展开和组合文档
少用:
// SUBOPTIMAL
var pipeline = [
// Unpack each product from the each order's product as a new separate record
{"$unwind": {
"path": "$products",
}},
// Match only products valued over 15.00
{"$match": {
"products.price": {
"$gt": NumberDecimal("15.00"),
},
}},
// Group by product type
{"$group": {
"_id": "$_id",
"products": {"$push": "$products"},
}},
];
多用:
// OPTIMAL
var pipeline = [
// Filter out products valued 15.00 or less
{"$set": {
"products": {
"$filter": {
"input": "$products",
"as": "product",
"cond": {"$gt": ["$$product.price", NumberDecimal("15.00")]},
}
},
}},
];
refer: Unpack Array & Group Differently
尽早过滤
完整过滤
以使用原始字段而非计算结果字段,以便使用索引。
如针对
[
{
customer_id: 'elise_smith@myemail.com',
orderdate: ISODate('2020-05-30T08:35:52.000Z'),
value: NumberDecimal('9999')
}
{
customer_id: 'elise_smith@myemail.com',
orderdate: ISODate('2020-01-13T09:32:07.000Z'),
value: NumberDecimal('10101')
}
]
不用
// SUBOPTIMAL
var pipeline = [
{"$set": {
"value_dollars": {"$multiply": [0.01, "$value"]}, // Converts cents to dollars
}},
{"$unset": [
"_id",
"value",
]},
{"$match": {
"value_dollars": {"$gte": 100}, // Peforms a dollar check
}},
];
改用
// OPTIMAL
var pipeline = [
{"$set": {
"value_dollars": {"$multiply": [0.01, "$value"]},
}},
{"$match": { // Moved to before the $unset
"value": {"$gte": 10000}, // Changed to perform a cents check
}},
{"$unset": [
"_id",
"value",
]},
];
进行部分匹配
如果match的内容是计算后的字段值而不是原始字段值,以致索引无法使用,那么可以考虑添加额外的match以在开头先进行过滤。