skip to Main Content

This is the update statement:

const cart = await Cart.findOneAndUpdate({
        userId: userId,
        'items._id': itemId,
        'items.product': productId,
        'items.size': size,  
        'items.color': color, 
    }, {
        $set: {
            'items.$.quantity': quantity
        }
    }, {
        new: true
    }).populate({
        path: 'items.product',
        model: 'Product'
    })

This is the new quantity to be applied to the array:

newQuantity {
  itemId: '625065c99edbfad52ac3afce',  
  productId: '6205a4565c0caba6fb39cd5d',
  size: '3',
  quantity: '3',
  color: 'blue2'
}

This is the data in the database, the first item of the array is updated with the new quantity rather than the second item that meets the query criteria shown above.

{
  "_id": {
    "$oid": "623a1f208ea52c030dc331a5"
  },
  "userId": {
    "$oid": "623a1f208ea52c030dc331a3"
  },
  "items": [
    {
      "quantity": 2,
      "product": {
        "$oid": "6205a4565c0caba6fb39cd5d"
      },
      "size": "3",
      "color": "blue1",
      "prodImage": "mom-jeans-3.1.png",
      "_id": {
        "$oid": "625065c69edbfad52ac3afc2"
      }
    },
    {
      "quantity": 1,
      "product": {
        "$oid": "6205a4565c0caba6fb39cd5d"
      },
      "size": "3",
      "color": "blue2",
      "prodImage": "mom-jeans-5.1.png",
      "_id": {
        "$oid": "625065c99edbfad52ac3afce"
      }
    },
    {
      "quantity": 1,
      "product": {
        "$oid": "6205a4565c0caba6fb39cd5d"
      },
      "size": "3",
      "color": "blue3",
      "prodImage": "mom-jeans-4.1.png",
      "_id": {
        "$oid": "625065cc9edbfad52ac3afdc"
      }
    }
  ],
      "__v": 0
    }

2

Answers


  1. ‘$’ operator only update the first element found.

    You should use $[] operator:

    const cart = await Cart.findOneAndUpdate({
        userId: userId,
        'items._id': itemId,
        'items.product': productId,
        'items.size': size,  
        'items.color': color, 
    }, {
        $set: {
            'items.$[].quantity': quantity
        }
    }, {
        new: true
    }).populate({
        path: 'items.product',
        model: 'Product'
    })
    

    Try it.

    Login or Signup to reply.
  2. You can use array filters to get the desired output:

    The userId into find query will filter across all documents, and the array filter will find the object in the array which match your condition.

    db.collection.update({
      "userId": userId
    },
    {
      "$set": {
        "items.$[item].quantity": quantity
      }
    },
    {
      "arrayFilters": [
        {
          "item._id": itemId,
          "item.product": productId,
          "item.size": size,
          "item.color": color
        }
      ]
    })
    

    Example here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search