Firstly, here is my "User" collection simplified down to only the relevant fields:
[
{
_id: "10",
groups: [
"1"
],
notifications: [
{
notificationType: "message-like",
msgId: "3",
read: false,
likers: ["steve", "joe"]
}
]
},
{
_id: "20",
groups: [
"1",
"2"
],
notifications: [
{
notificationType: "message-like",
msgId: "1",
read: false,
likers: ["frank", "bob"]
},
{
notificationType: "message-like",
msgId: "2",
read: false,
likers: ["bob"]
}
]
}
]
I need to:
- Find the document with the matching "_id"
- Look for the notification with matching "notificationType" and "msgId"
- If that object is found, add to the "likers" array, move the notification object to the first position, and set "read" to false if true
- If the object is not found, push a new notification object to the array
Basically, I need to do the following in MongoDB:
for (let doc of documents) {
if (doc._id === "20") {
let notificationFound = false
doc.notifications.forEach((notif, i) => {
if (
notif.notificationType === "message-like"
&& notif.msgId === "2"
) {
notif.likers.push("joe")
if (notif.read === true) notif.read = false
notifications.unshift(notifications.splice(i, 1)[0]) //move notification to 1st position
notificationFound = true
}
})
if (!notificationFound) doc.notifications.push(newNotificationObject)
}
}
What is a clean way to do this in MongoDB/Mongoose?
2
Answers
Figured it out. So far this is working well:
You can use the
findOneAndUpdate
method with the aggregation pipeline