1

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 2

2

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

Sign up to request clarification or add additional context in comments.

1 Comment

All 3 options worked perfectly. Thank you very much !
0

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 }
    }
  }
 )

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.