问题
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.
回答1:
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 } } ) )
回答2:
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");
来源:https://stackoverflow.com/questions/51618537/how-to-toggle-an-element-in-array-in-mongodb