2017-05-25 10 views
1
Below is my JSON and I want to update the title:'second title' to title:'new title' inside videos array in the below JSON. 

{ 
    "_id" : "1234", 
    "username" : "test", 
    "playlists" : [ 
     { 
      "name" : "abc",   
      "videos" : [ 
       { 
        "title" : "first title" 
        "desc" : "first description", 
       }, 
       { 
        "title" : "second title" 
        "desc" : "second description", 
       }, 
      ] 
     }, 
     { 
      "name" : "def",   
      "videos" : [ 
       { 
        "title" : "third title" 
        "desc" : "third description", 
       }, 
       { 
        "title" : "fourth title" 
        "desc" : "fourth description", 
       }, 
      ] 
     }, 
    ] 
} 

Wie werde ich das tun? Ich unten Abfrage versucht, aber keine luck.It immer aktualisiert nur das erste Objekt innerhalb VideosAktualisierung der zweite Ebene verschachteltes Objekt innerhalb Array von Objekten MongoDB

db.xyz.update(
{ username: 'test','playlists.videos.title' : 'second title' }, 
{ $set:{'playlists.0.videos.$.title' : "new title" }} 
); 

Wenn ich $ ersetzen Mit 0 und 1 konnte ich erreichen, was ich will, aber ich habe nicht den Positionsschlüssel/Index, wie es irgendwo sein kann. Ich kann es nicht umstrukturieren, da meine Daten bereits in diesem Format vorliegen.

+0

Die beste Lösung zu erhalten, die Arrays nicht verschachtelt werden in erster Linie ist zu tun. Dies ist in Ihrem Fall sehr einfach. Anstatt "videos" -Arrays in ein "playlists" -Array zu stellen, müssen Sie einfach das Dokumentarray 'videos' machen und eine" "playlist" "-Eigenschaft in jedes" video "-Dokument einfügen. Siehe die [positionelle $ Operator-Dokumentation] (https://docs.mongodb.com/manual/reference/operator/update/positional/), die erklärt, warum geschachtelte Array-Aktualisierungen nicht funktionieren können. –

+0

Ich habe Namen und ähnliche Schlüssel wie JCnumber, Startdatum, Enddatum usw. in der Wiedergabeliste, die mit einem anderen Formular hinzugefügt wurde und Videos werden mit anderen Form hinzugefügt, daher wird Ihre Lösung nicht funktionieren! Hast du noch einen anderen Vorschlag als den JSON zu wechseln? –

+0

Hey. Ich sage dir nur, was ** wird ** funktionieren, denn so ist MongoDB entworfen. Wenn Sie ein Array innerhalb eines anderen verschachteln, funktioniert die Positionsanpassung für Arrays ** nicht **. So einfach ist das wirklich. Verwenden von absoluten Indizes ** BAD **. Ersetzen der gesamten Array-Strukturen ** BAD **. Früher oder später müssen Sie "in den sauren Apfel beißen" und erkennen, dass das Verschachteln von Arrays nicht das Richtige ist. –

Antwort

0

Dieses verschachtelte Array-Dokument kann nicht mithilfe des Positionsoperators ausgeführt werden, da es sich um eine limitation of mongoDB handelt.

Aber das mit $unwind und $group der Aggregation durchgeführt werden kann Pipeline

Ansatz:

$unwind - Gebrauchte unsere Arrays entspannen, wird es verwendet, zweimal, da wir zwei Arrays haben.

$project - Projizieren Sie das Dokument mit dem Update, das wir

$cond tun wollen - Verwenden Zustand zusammen mit Projekt in Aggregation Pipeline hinzuzufügen, um das gewünschte Ergebnis zu dem Ausgang

$group - Sobald wir unsere gewünschten projizierten Ergebnis, wir müssen es wieder in das ursprüngliche Dokumentformat bringen.

$push - Verwenden Sie drücken Sie die Array-Format

Wir hatten zwei verschachtelte Arrays in unserem Dokument hinzufügen und jetzt haben wir es abgerollt, so das Originaldokument zurückbekommen wir zwei $ Gruppe und $ drücken gemeinsam verwenden müssen mal. Zuerst müssen wir das innere Array und dann das äußere Array gruppieren und schieben.

$out - Schließlich verwenden Sie dies, um die Ausgabe in eine Sammlung zu schreiben. Hier können wir den gleichen Namen der Sammlung angeben, um sie mit den neuen Ergebnissen zu überschreiben.

Mongo Shell Abfrage das gewünschte Ergebnis

db.mycollection.aggregate([ 
    { 
    $unwind: "$playlists" 
    }, 
    { 
    $unwind: "$playlists.videos" 
    }, 
    { 
    $project: { 
     "_id": 1, 
     "username": 1, 
     "playlists.name": 1, 
     "playlists.videos.desc": 1, 
     "playlistsvideostitle": { 
     $cond: { 
      if: { 
      $eq: [ 
       "$playlists.videos.title", 
       "second title" 
      ] 
      }, 
      then: "My New title", 
      else: "$playlists.videos.title" 
     } 
     } 
    } 
    }, 
    { 
    $group: { 
     _id: { 
     "_id": "$_id", 
     "username": "$username", 
     "playlistname": "$playlists.name" 
     }, 
     "videos": { 
     $push: { 
      "title": "$playlistsvideostitle", 
      "desc": "$playlists.videos.desc" 
     } 
     } 
    } 
    }, 
    { 
    $group: { 
     _id: "$_id._id", 
     "username": {$first: "$_id.username"}, 
     "playlists": { 
     $push: { 
      "name": "$_id.playlistname", 
      "videos": "$videos" 
     } 
     } 
    } 
    }, 
{$out:"mycollection"} 
]) 
Verwandte Themen