Home > Back-end >  MongoDB: Delete documents from array in multiple documents
MongoDB: Delete documents from array in multiple documents

Time:09-25

I'm still getting to know MongoDB and NoSql databases, and i'm trying to update a collection.

in my collection, i have multiple documents that look like this:

{
    "name": "store1",
    "products": [
        {
            "name": "product 1",
            "reviews": [
                {
                    "user": "john doe",
                    "stars": 5,
                },
                {
                    "user": "jane doe",
                    "stars": 1,
                }
            ]
        },
        {
            "name": "product 2",
            "reviews": [
                {
                    "user": "jane doe",
                    "stars": 3,
                }
            ]
        }
    ]
}

Each document has a document array "products" and each document in that array has a document array "reviews"

For each document in the collection, i want to delete from "products" the documents that have at least a review with 1 star = "stars": 1.

So, for the example above, the document would look like this after the update


{
    "name": "store1",
    "products": [
        {
            "name": "product 2",
            "reviews": [
                {
                    "user": "jane doe",
                    "stars": 3,
                }
            ]
        }
    ]
}

CodePudding user response:

You can use $pull operator to remove an object within the array.

db.collection.update({
  "products.reviews.stars": 1
},
{
  "$pull": {
    "products": {
      "reviews.stars": 1
    }
  }
})

Example here

CodePudding user response:

Query (aggregate pipeline way, requires mongodb 4.2 )

  • you dont need aggregate pipeline here but you could do it like this also ​

Test code here

db.collection.update({},
[
 ​{
   ​"$set": {
     ​"products": {
       ​"$filter": {
         ​"input": "$products",
         ​"cond": {
           ​"$not": [
             ​{
               ​"$in": [
                 ​1,
                 ​"$$p.reviews.stars"
               ​]
             ​}
           ​]
         ​},
         ​"as": "p"
       ​}
     ​}
   ​}
 ​}
])

Because you have only 1-5 stars filter is empty else "products.reviews.stars": 1, could be used. (even if you had index on stars it would have so low selectivity that would make things worse probably)

  • Related