Home > Blockchain >  How to delete object from array in a document by using it index
How to delete object from array in a document by using it index

Time:07-08

I have this object in mongodb atlas:

{
   _id: new ObjectId("62bf2315503e821576e53c53"),
   foodName: 'food name',
   foodPrice: '17',
   category: 'sweets',
   foodDesc: 'this is some random text',
   foodToppings: [
     { toppingName: 'a', toppingPrice: 5 },
     { toppingName: 'b', toppingPrice: 3 },
     { toppingName: 'c', toppingPrice: 5 }
   ],
   foodTags: [ 'a', 'b', 'c' ],
   createdAt: 2022-07-01T16:38:45.935Z,
   updatedAt: 2022-07-07T10:56:44.447Z,
   __v: 0,
   foodImgs: [
     {
       foodImgDisplayPath: 'https://fakepath.png',
       foodImgDisplayName: 'img_name-0'
     },
     {
       foodImgDisplayPath: 'https://fakepath.png',
       foodImgDisplayName: 'img_name-1',
     }
   ]
 }

and I'm using mongoose on the backend, I want to update this document by deleting the second object which it's index == 1, what I'm doing now is like:

await FoodsModel.findOneAndUpdate(
{ _id: foodId },
    { $pull: { foodImgs: { foodImgDisplayName: prevFoodImgName } } },
    { multi: true }
)

it works by pulling the object by using it's key: foodImgDisplayName that I passed in the params, but I want to remove (pull) it by using object index which I also have access to from req.query

My question are there any way to pull object from array by using its index in mongoose ?

Thanks a lot

CodePudding user response:

Inspired by this answer, one option is:

db.FoodsModel.findOneAndUpdate(
{ _id: foodId },
 [{$set: {foodImgs: {
        $reduce: {
          input: "$foodImgs",
          initialValue: [],
          in: {$concatArrays: [
              "$$value",
              [{$mergeObjects: [{data: "$$this"}, {inx: {$size: "$$value"}}]}]
            ]
          }
        }
      }
    }
  },
  {$set: {
      foodImgs: {
        $filter: {
          input: "$foodImgs",
          cond: {$ne: ["$$this.inx", indexToRemove]}
        }
      }
    }
  },
  {$set: {foodImgs: {$map: {input: "$foodImgs", in: "$$this.data"}}}}
])

See how it works on the playground example

  • Related