0

I have a few mongodb documents having an array called states in it. A sample document is given below .

{ "_id":ObjectId("xxxxxxxxxx"),
  "states":[
             {"place":"EU","skId":"SK01"},
             {"place":"IN","skId":"SK05"},
             {"place":"NZ","skId":"SK08"}
           ]
}

If I get a new object I have to push into the states array of the respective document if the 'place' key of new object does not matches those in the array , else in case if the 'place' key of the new object matches with any of the object in array then I have to replace or update that object in array with my new object. I am currently able to insert new objects into array (case 1) but unable to update (case 2).Adding my code and expected output below.

case 1 -->

new object  --> {"place":"KL","skId":"SK08"}
expected output : { "_id":ObjectId("xxxxxxxxxx"),
                    "states":[
                              {"place":"EU","skId":"SK01"},
                              {"place":"IN","skId":"SK05"},
                              {"place":"NZ","skId":"SK08"},
                              {"place":"KL","skId":"SK08"}
                             ]
                   }

case 2 -->

new object  --> {"place":"NZ","skId":"SK01"}
expected output : { "_id":ObjectId("xxxxxxxxxx"),
                    "states":[
                              {"place":"EU","skId":"SK01"},
                              {"place":"IN","skId":"SK05"},
                              {"place":"NZ","skId":"SK01"}
                              
                             ]
                   }

my code :

var query  = {"_id": ObjectId(xxx)}
var arr = [];
db.collection('Regions').find(query).toArray().then((data) => {
   arr = data[0]["states"];
   const index = arr.findIndex((e) => e.place === reqBody.place);
   var obj = {"place":reqBody.place,"skId":reqBody.skId};
        if (index > -1) {
                arr[index] = obj;
                  } else {
                     arr.push(obj);
                          }
   var newStates={"states":arr}
   var newStateValue = {$set:newSquad};
                            
   db.collection("Regions").updateOne(query, newStateValue, function(err, result) {
                                if(err){
                                    resolve({
                                        "error": ""+err+"",
                                        "statuscode": "404"
                                    });
                                }
   })
 })
       
Immanuel
  • 55
  • 1
  • 6
  • You can refer to the following question's answer. [Can mongo upsert array data.](https://stackoverflow.com/questions/13588342/can-mongo-upsert-array-data) – Sandeep Bochaliya Oct 01 '21 at 11:35

1 Answers1

0

You can do the followings in an aggregation pipeline:

  1. $match to filter your intented documents
  2. $addFields with $map to conditionally update the matched document in the states array if any array entry matched
  3. $setUnion the result in step 2 with an array of your input document as the insert case for no array entry found
  4. $merge back to the original document to update

Here is the Mongo playground for your reference.

ray
  • 11,310
  • 7
  • 18
  • 42