Home > Mobile >  Update MongoDB document with its own fields
Update MongoDB document with its own fields

Time:04-13

I'm trying to make a popularityIndex field for my mongodb documents like this:

popularityIndex: {
    type: Number,
    default: function() {
        return this.views.count * 0.3   this.upVoted.count * 0.3 - this.downVoted.count * 0.1 - ((new Date().getTime() - this.creationDate.getTime())) * 0.2
    },
},

I was wondering if there is a way to update this field whenever one of the fields it depends on gets update, while keeping the atomicity, or getting the fields when updating, something like this:

await Model.updateOne({ _id }, { 
       $set: { popularityIndex: 'views.count' * 0.3   'upVoted.count' * 0.3 - 'downVoted.count' * 0.1 - ((new Date().getTime() - 'creationDate'.getTime()) / 10000000) * 0.2 }
})

These are the fields that I need for updating and the last one is the one that gets updated:

{ 
  "upVoted": {
       "count": "2"
  },
  "downVoted": {
       "count": "3"
  },
  "views": {
       "count": "5"
  },
  "creationDate": "2022-04-11T16:02:39.956 00:00",
  "popularityIndex": "1.453"
}

So if the document receives an upvote, I'll have to update the popularity index too:

await Model.updateOne({ _id }, {
   $inc: { 'upVoted.count': 1 }
}

await Model.updateOne({ _id }, {
   $set: { popularityIndex: this.views.count * 0.3   this.upVoted.count * 0.3 - this.downVoted.count * 0.2 - ((new Date().getTime() - this.creationDate.getTime())) * 0.2 }
}) // <-- this is the part I don't know

CodePudding user response:

Maybe like this

db.collection.updateOne({ _id }, [
  {
    $set: {
      popularityIndex: {
        $sum: [
          { $multiply: [ "$views.count", 0.3 ] },
          { $multiply: [ "$upVoted.count", 0.3 ] },
          { $multiply: [ "$downVoted.count", -0.2 ] },
          { $multiply: [ { $dateDiff: { startDate: "$creationDate", endDate: "$$NOW", unit: "second" } }, -0.2 ] }
        ]
      }
    }
  }
])

Mongo Playground

  • Related