I have searched the web for possible solutions. Basically a field needs to be deleted where the id of an object in an array of objects meets a specific condition.
As a newbie to Mongodb I am not sure where exactly to look for relevant examples.
I want to delete the object where id = 0. The language used will be Javascript.
Not quite sure how to go about it though.
Look at the picture below . In red is an id, each registered user will have their own id. Each user will have a cart associated with their id. In the cart is productsInCart-->products which has fields like id, price etc.
So what happens is the users id is selected then the product(object) deleted where the specific product id = 0. The product id is shown with an arrow in the picture and I guess the Object to be deleted would the one at index = 0 also shown by a red arrow. The same could be done with any other Object at index 1 or 2 or anywhere.
I tried using $pull,$unset and the basics found online but the thing is that accessing the product id field requires a very specific command which I am not sure how to write it in Javscript . In sql it would be something Delete Object Where user id = new ObjectId("66a35c99784aa722b15c9801") and product id = 0
Avoid creating nested array fields. This is considered an anti-pattern and introduces unnecessary complexity to the query. Consider keeping just the cart
level.
[
{
...,
"cart": [
{
"product": {
"id": 0,
"name": "iPad 11inch",
"imageUrl": "./images/ipad.jpg",
"title": "Apples",
"description": "Apples are <span class=\"label label-info\">25 CHF each</span>",
"price": 25
},
"quantity": 2
},
...
]
}
]
You can simplify the query to be like this:
db.collection.update({
"cart.product.id": 0
},
{
"$pull": {
"cart": {
"product.id": 0
}
}
})
If you need to stick with your current schema, you will need a sophisticated aggregation pipeline. You need to iterate the cart
array with $map
, then use $filter
to iterate through the productsInCart
array to perform the filter. Finally, use $mergeObjects
to update the result back to cart
level.
db.collection.update({
"cart.productsInCart.product.id": 0
},
[
{
"$set": {
"cart": {
"$map": {
"input": "$cart",
"as": "c",
"in": {
"$mergeObjects": [
"$$c",
{
"productsInCart": {
"$filter": {
"input": "$$c.productsInCart",
"as": "p",
"cond": {
"$ne": [
"$$p.product.id",
0
]
}
}
}
}
]
}
}
}
}
}
])