Search code examples
mongodbmongoosemongodb-queryaggregation-framework

Mongoose updates : Increment a counter and reset to 0 on a new date


I have a schema that looks like this:

var Counter = new Schema ({
 _id: ObjectId,
 date: Date,
 counter: Number
})

On the request, I send date of a day and expect the date to be added and the counter to increase. Now when I add, a counter gets incremented ie 1,2,3 etc and a date gets added.

Now here is a problem: I want a counter to reset to 0 when a different date is given,(such to say on every new day, the counter should start at 0) and then start a counter increment again etc...

This is my code on how I have tried:

Counter.findOneAndUpdate(
  { 
   $set:{
     "date: thedate",
   },
   $inc: {
     "counter: counter+1"
    }
)

How do I achieve this ?

UPDATE FOR MORE CLARIFIATION

Take this example of two documents

{ 
  "_id": ObjectId("1111"), 
  "date": "2020-04-13", 
  "counter": 0, 
}

{ 
  "_id": ObjectId("2222"), 
  "date": "2020-04-29", 
  "counter": 0, 
}

My collection has more than one document. I want to update the document based on its id. For this case i want to update the 1st document of id 1111

Now if give an input date, say 2020-04-13 and id of '1111' which matches the first document, it should increment the couter to 1. If I give an the same date again (with same id of 111) it should increment the counter to 2.

If again I give an input date of 2020-04-14(which is another date) on the same first document of id 1111 it should reset the counter to 0.

Now How do I achieve this?


Solution

  • As you can execute update-with-an-aggregation-pipeline in .update() operations starting MongoDB version >= 4.2, try below querie :

    Counter.findOneAndUpdate(
        { _id: ObjectId("............") }, // filter query - Input of type ObjectId()
        /** Update date field with input & re-create 'counter' field based on condition */
        [{
          $addFields: {
            date: inputDate, // Input type of date, In general Date is saved in MongoDB as ISODate("2020-05-06T00:00:00.000Z")
            counter: { $cond: [ { $eq: [ "$date", inputDate ] }, { $add: [ "$counter", 1 ] }, 0 ] }
          }
        }]
      )
    

    Test : Test aggregation pipeline here : mongoplayground