mongodb使用bucket处理趋势图的问题
假设现在又日趋势,周趋势,月趋势的图表需要展示,我们可以通过以下的函数获取到bucket的boundary
function getTrendMatch (trendType, fieldName) {
let dateMatch = {}
let boundaries = []
switch (trendType) {
case 'day':
dateMatch = {
$gt: moment().subtract(30, 'days').endOf('day').toDate(),
$lt: moment().endOf('day').toDate()
}
for (let i = 29; i >= -1; i--) {
boundaries.push(moment().subtract(i, 'days').startOf('day').toDate())
}
break
case 'week':
dateMatch = {
$gt: moment().subtract(12, 'week').endOf('week').toDate(),
$lt: moment().endOf('week').toDate()
}
for (let i = 11; i >= -1; i--) {
boundaries.push(moment().subtract(i, 'week').startOf('week').toDate())
}
break
case 'month':
dateMatch = {
$gt: moment().subtract(12, 'month').endOf('month').toDate(),
$lt: moment().endOf('month').toDate()
}
for (let i = 11; i >= -1; i--) {
boundaries.push(moment().subtract(i, 'month').startOf('month').toDate())
}
break
case 'all':
default:
}
return {
match: dateMatch,
bucket: {
groupBy: `$${fieldName}`,
boundaries: boundaries,
default: 'other',
output: {
count: { $sum: 1 },
dates: { $push: `$${fieldName}` }
}
}
}
}
然后通过以下的业务代码来使用:
let { bucket, match } = getTrendMatch(trendType, 'testdate')
let list = await Model.aggregate([
{
$match: {
testdate: match
}
},
{
$bucket: bucket
},
{
$project: {
_id: -1,
boundary: '$_id',
// start: { $arrayElemAt: ['$dates', 0] },
// end: { $arrayElemAt: ['$dates', -1] },
amount: '$count'
}
}
])
let dataMap = {}
list.forEach((item) => {
dataMap[item.boundary] = item.amount
})
rows = bucket.boundaries.slice(0, -1).map((boundary, key) => {
return {
start: boundary,
end: bucket.boundaries[key + 1],
amount: dataMap[boundary] || 0
}
})
这样,我们就获得了边界日期start及end, 以及这个日期内的数据量,可以展示成一下的折线图的方式: