I have an array of string (ObjectIds
) in mongoDB.
I want to toggle an element in that array: If that element exists in the array, remove it, otherwise push that element.
Example:
arr = ["5b608c0769698c3990c64ef3","5b608c0769698c3990c64ef4"]
element = ["5b608c0769698c3990c64ef3"]
Final array:
arr = ["5b608c0769698c3990c64ef4"]
My use-case:
I am creating a blog website and in the Blog Schema I am storing the id of each user who has liked that blog, so that I can highlight the like button when blog is shown to the user.
If you are updating the document, you can use the pipeline within the update. But this feature is available with MongoDB version 4.2 or later.
db.collection.update(
{ },
[
{
$set: {
arr: {
$cond: [ { $in: [ element, "$arr" ] },
{ $setDifference: [ "$arr", [ element ] ] },
{ $concatArrays: [ "$arr", [ element ] ] }
]
}
}
}
]
)
NOTE: Assuming the variable element
is a string value.
If you are just querying you can use the following aggregation:
db.collection.aggregate([
{
$addFields: {
arr: {
$cond: [ { $in: [ element, "$arr" ] },
{ $setDifference: [ "$arr", [ element ] ] },
{ $concatArrays: [ "$arr", [ element ] ] }
]
}
}
}
] )
But, if you are using MongoDB version earlier than 4.2, then you can use the aggregate output from above to update the document:
db.collection.aggregate( [
// aggregation pipeine from above ...
] ).forEach( doc => db.collection.updateOne( { _id: doc._id }, { $set: { arr: doc.arr } } ) )
Its maybe not the best solution, but a easy one. You can add your element to the array with $addToSet
and check with nModified
if you modified the array. 0
means it already exist, and 1
mean you added new Element to it.
So you use mongoose as you said then you have a Model lets say Post
. I dont know witch backend langauge you use, but i will show it with node.js here:
let result = await Post.updateOne({ _id: "someId" }, {
$addToSet: {
arr: element
}
})
if(result.nModified === 0){
//0 means, no modifikation, that means its already liked
await Post.updateOne({ _id: "someId" }, {
$pull: {
arr: element
}
})
}
response.send("Done");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With