Skip to content
Advertisement

Update single field value in nested array without modifying other ones?

I am trying to modify single field value, but whenever I do it it erases all other fields leaving updated field only, how can I modify a single field witouth affecting the other ones? so far this is what I’m doing:

//
        $updateResult2 = $coll_rutas->updateOne(


            /* LIMIT TO ROUTE ID */
            [
                "_id" => new MongoDBBSONObjectId($ruta_id)
            ],


            /* UPDATE VALUE */
            [
                '$set' => [
                    'destinos.$[d]' => [
                        "horas" => "1",
                        "minutos" => "15",
                        "millas" => "150",
                        "orden" => "1",
                        "notas" => "demo notes",
                    ],
                ],
            ],


            /* WHERE FILTER */
            [
                "upsert" => true,
                'arrayFilters' => [
                    ['d.ciudad_id' => 47]
                ]
            ]

        );
        //var_dump($updateResult2); exit;

This is the original mongo Object:

"destinos": [
        {
            "ciudad_id": "47",
            "nombre_destino": "Salt Lake City, Utah",
            "horas": "0",
            "minutos": "0",
            "millas": "0",
            "orden": 1,
            "notas": null,
            "origenes": [
                {
                    "ciudad_id": "45",
                    "nombre_origen": "Provo, Utah",
                    "orden": 1,
                    "notas": null,
                    "base_price": 0
                }
            ]
        }
    ],

With my changes it erases origenes array, ciudad_id and nombre destino, leaving it this way:

"destinos": [
        {
            "horas": "1",
            "minutos": "15",
            "millas": "150",
            "orden": "1",
            "notas": "demo notes"
            ]
        }
    ],

Advertisement

Answer

With this code:

'$set' => [
       'destinos.$[d]' => [
        "horas" => "1",
        "minutos" => "15",
        "millas" => "150",
        "orden" => "1",
        "notas" => "demo notes",
       ],
     ]

you are targeting the destinos.$[d] element and replacing all of its contents with the new data structure.

You need to use the .(dot) notation to target each element in the nested array. It’s a bit verbose but this would work:

'$set' => [
       'destinos.$[d].horas' => "1",
       'destinos.$[d].minutos' => "15",
       'destinos.$[d].millas' => "150",
       'destinos.$[d].orden' => "1",
       'destinos.$[d].notas' => "demo notes"
 ]
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement