Javascript 猫鼬群以15秒为周期计数

Javascript 猫鼬群以15秒为周期计数,javascript,node.js,mongodb,mongoose,Javascript,Node.js,Mongodb,Mongoose,我有一个模型,它有一个createdAt对象,我需要得到文档的数量,每个文档按15秒分组 从表中选择COUNT(*),其中time\u stamp>=foo GROUP BY UNIX\u TIMESTAMP(time\u stamp)DIV 15的等价物是什么,其中返回在15秒内添加的文档数量。下面是一个工作示例,其中文档从中分组 00:00 - 00:14, 00:15 - 00:29, 00:30 - 00:44, 00:45: - 01:00 我相信这是你正在寻找的功

我有一个模型,它有一个createdAt对象,我需要得到文档的数量,每个文档按15秒分组


从表中选择COUNT(*),其中time\u stamp>=foo GROUP BY UNIX\u TIMESTAMP(time\u stamp)DIV 15的等价物是什么,其中返回在15秒内添加的文档数量。

下面是一个工作示例,其中文档从中分组

  00:00 - 00:14,
  00:15 - 00:29,
  00:30 - 00:44,
  00:45: - 01:00

我相信这是你正在寻找的功能,但如果没有留下评论

db.collection.aggregate([
  {$addFields: {
    // Add a numeric timestamp
    time: {
      $toLong: "$createdAt"
     }
  }},

  {$group: {
    _id: {
      // Divide by 15 sec and round down
      $floor: {
        $divide: [
          "$time",
          15000
        ]
      }
    },
    // Add the item count to the group output
    itemCount: {
      $sum: 1
    },
    // Add the item ids to an array (to help show the pipe works correctly)
    items: {
      $push: "$_id"
    }
  }},
  
  // Add a human readable date (again to help verify the pipe works)
  {$addFields: {
    date: {
      $convert: {
        input: {
          $multiply: [
            "$_id",
            15000
          ]
        },
        to: "date"
      }
    }
  }},

  {$sort: {
    date: 1
  }}

])
如果需要在管道中的两个文档之间填充数据,可以使用$acculate。(仅在4.4中提供)

只需添加以下阶段: 注意:取决于之前的排序asc

  {$group: {
    _id: null,
    docs: {
      $accumulator: {
        accumulateArgs: ["$$ROOT"],

        accumulate: function(state, group) {
          const lastGroup = state[state.length - 1];
          if (!lastGroup) {
            return [group];
          }

          // The amount of 'empty' spaces that need to be filled
          const needToFill = group._id - lastGroup._id - 1;

          const fillerContent = [];
          for (let i = 0; i < needToFill; i++) {
            // Current time block, subtract 1 to be at previous block
            // Subtract i to go back 1 block at a time
            // Multiply by 15000 sec to be a proper timestamp
            let fillingTimestamp = (group._id - 1 - i) * 15000;
            fillerContent.unshift({
              _id: fillingTimestamp,
              itemCount: 0,
              date: new Date(fillingTimestamp)
            })
          }

          return [...state, ...fillerContent, group]
        },
      
        init: function() {return []},
        merge: function(state1, state2) {return state1.concat(state2)},
        finalize: function(state) {return state},
        lang: "js"
      }
    }
  }},

  // Fix formatting
  {$unwind: '$docs'},
  {$replaceRoot: {newRoot: '$docs'}}
{$group:{
_id:null,
文件:{
美元累加器:{
累计搜索:[“$$ROOT”],
累积:功能(状态、组){
const lastGroup=state[state.length-1];
如果(!lastGroup){
返回[组];
}
//需要填充的“空”空间的数量
const needToFill=group.\u id-lastGroup.\u id-1;
常量fillerContent=[];
for(设i=0;i
如果您只是输出结果,那么只需使用.reduce(),这样我们就不会从数据库中膨胀传输

(与累加器中使用的功能完全相同)

res.reduce((状态、组)=>{
const lastGroup=state[state.length-1];
如果(!lastGroup){
返回[组];
}
//需要填充的“空”空间的数量
const needToFill=group.\u id-lastGroup.\u id-1;
常量fillerContent=[];
for(设i=0;i
如果itemCount为0,则是否有其他方法显示日期和itemCount是。我用几个不同的选项更新了答案。
res.reduce((state, group) => {
  const lastGroup = state[state.length - 1];
  if (!lastGroup) {
    return [group];
  }

  // The amount of 'empty' spaces that need to be filled
  const needToFill = group._id - lastGroup._id - 1;

  const fillerContent = [];
  for (let i = 0; i < needToFill; i++) {
    // Current time block, subtract 1 to be at previous block
    // Subtract i to go back 1 block at a time
    // Multiply by 15000 sec to be a proper timestamp
    let fillingTimestamp = (group._id - 1 - i) * 15000;
    fillerContent.unshift({
      _id: fillingTimestamp,
      itemCount: 0,
      date: new Date(fillingTimestamp)
    })
  }

  return [...state, ...fillerContent, group]
}, [])