Search code examples
mongodbnosqlcrud

Different Update Operation based on the condition [mongodb]


Hello stackoverflow community,

I have the following documents format at mongoDB (simplifed for easy readability)

{
Company : "Alpha",
Products : 
[
{ Name : "Car",
SalesRecord : [ <Obj>]},
{Name: "Plane",
SalesRecord : [<Obj>]}
]
}

The update document is in same format but will only consist of *one product of company (which can be existing or or new) and one new sales record of that product*

So How I want to do is
  1. first I will find the documents by Company Name
  2. Then I want to search in its products by Name keys,
  3. if Product is exists then I want to push a record document to its SalesRecord Array.
    if Product is not exists then I will add that new product document to the Products Array.

The sample query I have tried is as follows but the problem with this code is $push is not allowed in the $project State.

db.collection.findOneAndUpdate(
{Company:updateObj.Company},
    [
    {$project:{
        "Company": 1,
        "Products":{
        $switch :{
        branches:[
            {
                case:{$eq:['$Name',UpdateObj.Products[0].Name]},
                then: {$push:{'$Products.$.SalesRecord': UpdateObj.Products[0].SalesRecord[0}}
            },
            {
                case:{$ne:['$Name',UpdateObj.Products[0].Name]},
                then: {$push:{ Products:  UpdateObj.Products[0]}}
            }
   ]
    }}}})

Solution

  • I have managed to do the above by filtering each specific scenario and perform an update

    db.collection(name).bulkWrite(
    [
        {  /* first scenario is Both Company and the Product exists but update new Sales Object with same date`*/
            updateOne:{
                filter :{Company:chart[0].Company,'Products.Name' :chart[0].Products[0].Name},
                update : { $set:{
                    "Products.$.SalesRecord.$[elem]": chart[0].Products[0].SalesRecord[0]
                  }
                },
                arrayFilters: [{"elem.Date": chart[0].Products[0].SalesRecord[0].Date }]
            }
        },
        { /* second scenario is Both Company and the Products exists but no Sales object with same date exists */
       updateOne:{
                filter: {Company:chart[i].Company,'Products.Name': chart[i].Products[0].Name,'Products.SalesRecord.Date':{$ne:chart[0].Products[0].SalesRecord[0].Date}},
                update: {$push:{
                    "Products.$.SalesRecord": chart[i].Products[0].SalesRecord[0]
                }         }            }
        },
        {
            /* Third scenario is Company exists but Product not exists */
            updateOne:{
                filter: {Company:chart[i].Company,'Products.Name':{$ne:chart[i].Products[0].Name}},
                update: {$push:{'Products': chart[i].Products[0]}}
            }
        },
        {
           /* fourth is if Company not exists */
            updateOne:{
            filter: {Company:chart[i].Company},
            update: {$setOnInsert:{'Products': chart[i].Products}},
            upsert: true
            }
        },
    ],
    /* it needs to be ordered for not to be conflicted*/
    {ordered:true})