skip to Main Content

in the following example I have a company named Colors Company that owns many shops

{
    _id: ObjectId("78391283"),
    name: "Colors company",
    shops: [
        {shopID: ObjectId("123456a1cb"), income: 0},
        {shopID: ObjectId("2a1cb67890"), income: 0},
        {shopID: ObjectId("2a1cb010111"), income: 0},
        ...
      ],
}

I need to :
1- Loop on the shops array, find the requested array using {parsedBody.shopID}
2- Get use of the amount stored in “shop.$.income” as a number
2- Increase the income using {parsedBody.amountToAdd}

This is the POST request parsedBody :

{
    companyID: "78391283",
    shopID: "123456a1cb",
    amountToAdd: 200,
}

I’m using Next js 13.

Thanks for your help !

What i’ve tried :

const ObjectId = require("mongoose").Types.ObjectId;

Shops.findOneAndUpdate(
    { _id: parsedBody.shopID},
    {
        set: {
        // <-- missing loop here
        "shops.$.income": { parsedBody.amountToAdd + income }
        }
    }
)

I am expecting to loop through the shops array and update the income field.

2

Answers


  1. Option 1: This seems to be an easy option mongoDB 3.6+

    db.collection.update({},
    {
     "$inc": {
    "shops.$[x].income": 200
    }
    },
    {
     arrayFilters: [
      {
       "x.shopID": 2
      }
     ]
    })
    

    Playground1


    Option 2: Using update/aggregation mongoDB 4.2+

     db.collection.update({},
     [
     {
     $addFields: {
      shops: {
        "$map": {
          "input": "$shops",
          "as": "s",
          "in": {
            "$cond": {
              "if": {
                $eq: [
                  "$$s.shopID",
                  2
                ]
              },
              "then": {
                $mergeObjects: [
                  "$$s",
                  {
                    income: {
                      $sum: [
                        "$$s.income",
                        200
                      ]
                    }
                  }
                ]
              },
              "else": "$$s"
            }
          }
         }
        }
       }
      }
      ])    
    

    Playground2


    Option 3: Another simple option , Warning: This option need to be used when shopID is not expected to be found more then once in the shops array , since it will update only 1st found shop element , if there is more then one element in same document with the same shopID they will not be updated.

    db.collection.update({
       "shops.shopID": 2
    },
    {
     $inc: {
      "shops.$.income": 200
     }
    })
    

    Playground3

    Login or Signup to reply.
  2. You should move your income field in your Company document to your Shops document in your database design so that you can update different incomes for different shops.

     Shops.findOneAndUpdate(
      { _id: parsedBody.shopID},
      {
        set: {
         "income": { parsedBody.amountToAdd + income }
        }
      }
     )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search