Home > Blockchain >  MongoDB - Decrement a certain value in a nested object, but dont let it go below 0
MongoDB - Decrement a certain value in a nested object, but dont let it go below 0

Time:01-08

My MongooseSchema (simplified):

_id: (ObjectId)
storage: [
    {
        location: String
        storedFood:[
            {
             "name": String
             "code": String
             "weight": Number
            }
        ]     
    }
]

I want to dec the weight, but not below 0. There is a stackoverflow answer that does this(The second answer from @rpatel). Great! The problem here is that he uses a update-pipeline WITHOUT nested documents. I didnt find a source where I could learn something about mongdob pipelines and nested object (If you have any please let me know, I really want to learn complex pipelines)

Is someone here who could adapt the following code to decrement weight,where location equals for example "Dubai" and code equals for example "38102371982" ?

Code from @rpatel:

Mongo-Playground

Example-Document:

{
    "key": 1,
    value: 30
}
db.collection.update({},
[
  {
    $set: {
      "value": {
        $max: [
          0,
          {
            $subtract: [
              "$value",
              20
            ]
          }
        ]
      }
    }
  }
])

A ready playground.

CodePudding user response:

One option is to use double $map with $cond in order to get into the double nested array item:

db.collection.update(
  {storage: {$elemMatch: {location: wantedLoc}}},
  [{$set: {
      storage: {
        $map: {
          input: "$storage",
          as: "st",
          in: {$cond: [
              {$eq: ["$$st.location", wantedLoc]},
              {location: "$$st.location",
                storedFood: {$map: {
                    input: "$$st.storedFood",
                    in: {$cond: [
                        {$eq: ["$$this.code", wantedCode]},
                        {$mergeObjects: [
                          "$$this", 
                          {weight: {$max: [0, {$subtract: ["$$this.weight", reduceBy]}]}}
                        ]},
                        "$$this"
                    ]}
                  }
                }
              },
              "$$st"
          ]}
        }
      }
  }}]
)

See how it works on the playground example

  • Related