3

I have an issue in which I am not able to use the positional operator to update subdocuments because I am using MongoDB version 3.2 which doesn't support the positional operator $, and I am not able to upgrade MongoDB version to more than 3.2 due to the 32-bit MongoDB support

I want to change the value of the field order in the subdocument to the boolean value false

[
  {
    "_id": 1,
    "products": {
      "books": [
        {
          "id": 1,
          "ordered": true
        },
        {
          "id": 2,
          "ordered": false
        }
      ]
    }
  }
]

and if there is a mongoose way to do it , I would be thankfull

hamza
  • 65
  • 8

1 Answers1

1

Sadly not much you can do, if you know the index of the array you can use that:

db.collection.update({},
{
  "$set": {
    "products.books.0.ordered": false
  }
})

If you don't you need to find the document first and then update it:

const doc = await db.collection.findOne({});
if (doc) {
    const indexToUpdate = doc.products.items.map((item, index) => ({...item, index})).filter(v => v.item.ordered === true);
    if (indexToUpdate.length) {
        const setBody = {}
        indexToUpdate.forEach((item) => {
            const key = `products.books.${item.index}.ordered`
            setBody[key] = false;
        })
        await db.collection.update({},
            {
                "$set": setBody
            })
    }
}
Tom Slabbaert
  • 21,288
  • 10
  • 30
  • 43
  • Hello, Thank you For answering, this method it requires to perform multiple requests to the database, I used your method and it works , i wondered if it is possible to use the same method with mongoose – hamza Aug 24 '22 at 14:53
  • Yes it is, you can also update the entire array in 1 go – Tom Slabbaert Aug 24 '22 at 14:59
  • I have updated my answer to reflect this, sadly in version 3.2 you can't avoid executing a `find` first without knowing the indexes. The only way if to use a `for` loop and generate the set condition based on some predefined length if you have some max length you can assume. – Tom Slabbaert Aug 24 '22 at 15:03