axfg
axfg

Reputation: 65

How to update the element of an array in mongo document using node js?

here is my mongo document sample:

_id:ObjectId("60e54vfb99f346446618269")
count:Array
0:Object
   date:2021-07-03T15:13:42.200+00:00
   count:35
1:Object
   date:2021-07-03T15:13:42.200+00:34
   count:38

I am using node to handle api requests. I want to get the last element of the array from mongo and check the date if the date is a new date than the existing date, I want to insert that data. If it is the same as existing, I want to update the count in the exisitng date object.

How to do it in node? I'm using select and slice but I'm unable to get the last date and compare it. How to get the last element's date and compare it with request's date and post to the db?

This is the object I want to send:

router.route("/update/").put((req, res) =>{
    const count_update = {
        date: new Date(),
        count: req.body.count
    }

Upvotes: 1

Views: 168

Answers (1)

turivishal
turivishal

Reputation: 36154

You can try update with aggregation pipeline starting from MongoDB 4.2,

  • $cond to check if the last element's date is greater than the input date
  • $substr to get first 10 characters means "yyyy-mm-dd" from full date
  • yes,
    • $concatArrays to concat current count array with new date and count fields object
  • no,
    • $map to iterate loop of count array and check condition if date match with last element's date then update count field
    • $mergeObjects to merge current object with updated count object
var _id = "60e54vfb99f346446618269",
  date = new Date("2021-07-04T15:13:42.200+00:35"),
  count = 20;
var searchDate = date.toISOString().slice(0,10); // 2021-07-04

await SchemaModel.updateOne(
  { _id: _id },
  [{
    $set: {
      count: {
        $cond: [
          {
            $gt: [searchDate, { $substr: [{ $last: "$count.date" }, 0, 10] }]
          },
          {
            $concatArrays: [
              "$count",
              [{ date: date, count: count }]
            ]
          },
          {
            $map: {
              input: "$count",
              in: {
                $mergeObjects: [
                  "$$this",
                  {
                    $cond: [
                      {
                        $eq: ["$$this.date", { $last: "$count.date" }]
                      },
                      { count: count },
                      {}
                    ]
                  }
                ]
              }
            }
          }
        ]
      }
    }
  }]
)

Playground

Upvotes: 1

Related Questions