MongoDB update fields in a nested array

MongoDB update fields in a nested array

How can I set "play" to "play photos" in an array of photos?

I only know his _id.

"_id": ObjectId("4f41a5c7c32810e404000000"),
"albums": [
{
    "_id": ObjectId("4f545d1bc328103812000000"),
    "name": "album1" ,
    "photos":[{
        "_id": ObjectId("4f545d1bc328103812d00000"),
        "name":"travel photo"
    },{
        "_id": ObjectId("4f545d1bc328103812c00000"),
        "name":"play"
    }]
},
{
    "_id": ObjectId("4f545f56c328103c12000000"),
    "name": "album2" 
},
{
    "_id": ObjectId("4f545f68c328103012000000"),
    "name": "album3" 
},
{
    "_id": ObjectId("4f546642c328103c12000001"),
    "name": "album4" 
}]
+3
source share
2 answers

You can not. The positioning operator is available only for the first array in the document hierarchy. Thus, you cannot manipulate individual elements of deeper nest arrays.

This is a known issue and is planned for development here: https://jira.mongodb.org/browse/SERVER-831

Until this time, you will have to normalize your circuit a bit. I'm afraid.

+6
source

Tonilin You Cant , , , , name play photo, photos, name play. , :

$m = new Mongo();
$db=$m->yourdatabase;
//testarray is my collection name
$result=$db->testarray->find();
$index='';
foreach($result as $res)
{
    if(array_key_exists("albums",$res))
    {
        foreach($res['albums'] as $ralbum)
        {
            if(array_key_exists("photos",$ralbum))
            {
                foreach($ralbum['photos'] as $k=>$rphotos)
                {
                    if(array_key_exists("name",$rphotos))
                        if($rphotos['name']=='play')
                            $index=$k;
                }
            }
        }
    }
}
//echo $index;

//, , ...

if($index!=='')
{
    //Run like this in Shell
    //db.testarray.update({"albums.photos._id":ObjectId("4f545d1bc328103812d00000")},{'$set':{"albums.$.photos.1.name":"play132"}})
    $condition=array("albums.photos._id"=>new MongoId("4f545d1bc328103812d00000"));
    $data=array('$set'=>array("albums.$.photos.".$index.".name"=>"play photo"));
    $result=$db->testarray->update($condition,$data);
    $status=$db->Command(array('getlasterror'=>1));
    print_r($status);
}
0

All Articles