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 ] }
]
}
}
}
])