Aggregation count by period considering the past documents

As shown below, documents in the collection look like this.
The aggregation I need should count the number of devices monthly, the device should start being counted from the first month it appears, and from that month until the current month, independent of whether or not it appears again.

[
  {
    "device": 1,
    "date": ISODate("2022-7-10")
  },
  {
    "device": 2,
    "date": ISODate("2022-8-10")
  },
  {
    "device": 1,
    "date": ISODate("2022-9-11")
  },
  {
    "device": 3,
    "date": ISODate("2022-10-11")
  }
]

The output would be:

[
  {
    "_id": {
      year: 2022,
      month: 7
    },
    count: 1 // device 1
  },
  {
    "_id": {
      year: 2022,
      month: 8
    },
    count: 2 // device 1 and 2
  },
  {
    "_id": {
      year: 2022,
      month: 9
    },
    count: 2 // device 1 and 2
  },
  {
    "_id": {
      year: 2022,
      month: 10
    },
    count: 3 // device 1, 2 and 3 
  }
]

The difficult part with your use-case is that you want to count absent data.

To be able to count absent data usually involve some combination of $range, $map, $filter and $reduce to generate the holes in the data.

UNTESTED AND LOTS OF DETAILS LEFT OUT

start_month = 
end_month = 
start_date = 1st day of start_month
end_date = last day of last_month
all_months = [ array of months from start to current month ]
pipeline = [
  { "$match" : {
    "date" : { "$gte" : start_date , "$lte" : end_date }
  } } ,
  { "$sort" : {
    "date" : 1
  } } ,
  { "$group" : {
    "_id" : "$device" ,
    "first_occurrence" : { "$first" : "$date" }
  } } ,
  { "$set" : {
     "filtered_months" : {
       "$filter" : {
         "input" : all_months ,
         "cond" : { $gte: [ "$$this.first_occurence", start_month ] }
     }
  } } ,
  { "$unwind" : "$filtered_months" } ,
  { "$group" : {
    "_id" : { "$filtered_month" } ,
    "count" : { "$sum" : 1 } 
  } }
]

But personally, I would stop the aggregation after the $group with _id:$devices and would complete the data in the application back plane.

2 Likes

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.