mongodb使用bucket处理趋势图的问题

2020-07-09  本文已影响0人  awayisblue

假设现在又日趋势,周趋势,月趋势的图表需要展示,我们可以通过以下的函数获取到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, 以及这个日期内的数据量,可以展示成一下的折线图的方式:

上一篇下一篇

猜你喜欢

热点阅读