Luciano Borges
Luciano Borges

Reputation: 827

Update documents nested multiple levels in an array

I have this JSON structure in MongoDb and want to update changing a specific value of a particular item in a nested array. I would like to change the key targetAreaId from USER_MESSAGE to VISUAL_MESSAGE.

{
"_id" : "5cde9f482f2d5b924f492da2",
"scenario" : "SCENARIOX",
"mediaType" : "VISUAL",
"opCon" : "NORMAL",
"stepConfigs" : [ 
    {
        "stepType" : "STEPX",
        "enabled" : true,
        "configs" : [ 
            {
                "contentTemplateId" : "5cde9f472f2d5b924f492973",
                "scope" : "STANDARD",
                "key" : "CONTENT"
            }, 
            {
                "priorityId" : "5cde9f472f2d5b924f49224f",
                "scope" : "STANDARD",
                "key" : "PRIORITY"
            }, 
            {
                "targetAreaId" : "USER_MESSAGE",
                "scope" : "STANDARD",
                "key" : "TARGET_AREA"
            }
        ],
        "description" : "XPTO"
    }
],
"scope" : "STANDARD" }

How can I do it in the same time?

EDIT

I am trying this way:

var cursor = db.getCollection('CollectionX').find({
  "scenario": "SCENARIOX",
  "stepConfigs.stepType": "STEPX",
  "stepConfigs.configs.key": "TARGET_AREA"
});

if (cursor.hasNext()) {
    var doc = cursor.next();
    doc.stepConfigs.find(function(v,i) { 
        if (v.stepType == "STEPX") {
           doc.stepConfigs[i].configs.find(function(w,j) {
                if (w.key == "TARGET_AREA") {
                    var result = db.getCollection('CollectionX').update(
                        { "_id" : doc._id },
                        { "$set" : { doc.stepConfigs[i].configs[j].targetAreaId: "VISUAL_MESSAGE" }}
                    );
                }
           });
        };
    });
} else {
    print("Step does not exist");
}

But the error below is occurring:

Error: Line 15: Unexpected token .

Upvotes: 2

Views: 131

Answers (1)

Ptijohn
Ptijohn

Reputation: 231

I don't think that's possible.

You can update the specific element you want using this query:

db.test_array.updateOne({}, {
    $set: {
        "stepConfigs.$[firstArray].configs.$[secondArray].targetAreaId": "VISUAL_MESSAGE"
    }
}, {
    arrayFilters: [{
        "firstArray.stepType": "STEPX"
    }, {
        "secondArray.targetAreaId": "USER_MESSAGE"
    }]
})

But pushing in the same array at the same time does render this (this was for the original model, but it's still the same problem, you can't $set and $push in the same array this way):

> db.test_array.updateOne({"step.type":"B"},{$push:{"step.$.configs":{"className":"something"}}, $set:{"step.$.configs.$[secondArray].targetAreaId":"TA-1"}},{arrayFilters:[{"secondArray.targetAreaId":"TA-2"}]})
2019-09-06T13:53:44.783+0200 E QUERY    [js] WriteError: Updating the path 'step.$.configs.$[secondArray].targetAreaId' would create a conflict at 'step.$.configs' :

Upvotes: 1

Related Questions