MongoDB简单的TimeSeries

时间:2018-12-14 14:12:24

标签: javascript node.js mongodb mongoose time-series

我正在尝试构建一个简单的时间序列API,该API可以执行以下操作:

  1. 每天00小时,CRON作业都会去一个Facebook API,并且GET的多个facebook页面的粉丝计数,然后像这样将它们保存在mongoDB中:

{ "_id" : ObjectId("5c13b3663b720419c7806a4f"), "name" : "PageName", "dateUpdated" : "2018-12-17T00:00:00.000Z", "likes" : [ { "date" : "2018-12-14T00:00:00.000Z", "value" : NumberInt(74154) }, { "date" : "2018-12-15T00:00:00.000Z", "value" : NumberInt(89154) }, { "date" : "2018-12-17T00:00:00.000Z", "value" : NumberInt(86745) } ] }

CRON每天执行其工作时,都会使用当天的计数更新“喜欢”数组。

  1. 我通过传递页面名称和日期范围大概两天来查询API,然后API向我返回日期范围内“点赞”数组中两个对象之间的值和百分比的差异。

所以我很想像这样进行api调用:

https://api.com/likes?name=PageName&from=2018-12-14&to=2018-12-17

并得到一个像json的仓库:

{ before: 74154, now: 86745, change: 12.591, changePercent: +10% }

用mongo可以做到这一点吗?我想聚合是我需要的吗? 我对数据库和后端javascript编程还很陌生(我是前端程序),因此可以提供任何帮助。

顺便说一句,我的架构设计是否正确?我应该为Page创建一个Mongoose方案,然后为Likes Entry创建另一个方案,然后在Page Scheme中引用Likes Entry方案吗?

如果我正在忙碌,请问我您需要的任何信息,我会尽快做出回应。

谢谢!

1 个答案:

答案 0 :(得分:1)

一个简单的实现将使用聚合:

[
  {
    $unwind: {
      path: '$likes'
    }
  }, {
    $match: {
      'likes.date': {
        $gte: new Date('2018-12-14'), 
        $lte: new Date('2018-12-17')
      }
    }
  }, {
    $group: {
      _id: null, 
      first: {
        $first: '$$ROOT'
      }, 
      last: {
        $last: '$$ROOT'
      }
    }
  }, {
    $addFields: {
      before: '$first.likes.value', 
      now: '$last.likes.value'
    }
  }, {
    $addFields: {
      change: {
        $subtract: [
          '$now', '$before'
        ]
      }
    }
  }, {
    $addFields: {
      changePercent: {
        $multiply: [
          {
            $divide: [
              '$change', '$before'
            ]
          }, 100
        ]
      }
    }
  }, {
    $project: {
      before: 1, 
      now: 1, 
      change: 1, 
      changePercent: 1
    }
  }
]