MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

$push mit positionalem ($) in Upsert schlägt fehl

Upsert funktioniert nicht in verschachtelten Dokumenten in Aktualisierungsabfragen,

Sie können eine komplexe Aktualisierung mit einer Aggregationsabfrage versuchen, um Ihre Fälle zu bearbeiten, wenn Sie dies in einer einzigen Abfrage tun möchten,

Nehmen wir eine Beispieleingabe und sehen uns das Beispiel fallweise an,

Fall 1: Falls angegeben messages.from Feld existiert in messages Array

var to = "111";
var from = "222";
var subMessage = {
  message: "test",
  date: ISODate("2021-06-29T15:57:53.975Z")
};

Spielplatz

Fall 2: Wenn messages.from Feld existiert nicht im Array

var to = "111";
var from = "333";
var subMessage = {
  message: "test2",
  date: ISODate("2021-06-29T15:57:53.975Z")
};

Spielplatz

Fall 3: Wenn das Dokument nicht existiert

var to = "111";
var from = "333";
var subMessage = {
  message: "test2",
  date: ISODate("2021-06-29T15:57:53.975Z")
};

Spielplatz

Ihre letzte Abfrage wäre,

  • nur to markieren Bedingung in Abfrage
  • Teil aktualisieren, Zustand prüfen,
    • wenn from gefunden in messages Array dann:
      • $map Schleife von messages durchlaufen Array und Bedingung prüfen, wenn from gefunden dann aktuelle subMessages zusammenfügen Array mit neuer Eingabe subMessage mit $concatArrays , $mergeObjects um das aktuelle Objekt mit dem aktualisierten Objekt zusammenzuführen
    • else from not found then concat new message object array in current messages Array mit $cocnatArrays
  • upsert: true , um ein neues Dokument einzufügen, wenn es nicht in der Sammlung gefunden wird
db.pendingMessages.updateOne(
  { to: to },
  [{
    $set: {
      messages: {
        $cond: [
          { $in: [from, { $ifNull: ["$messages.from", []] }] },
          {
            $map: {
              input: "$messages",
              in: {
                $mergeObjects: [
                  "$$this",
                  {
                    subMessages: {
                      $cond: [
                        { $eq: ["$$this.from", from] },
                        {
                          $concatArrays: ["$$this.subMessages", [subMessage]]
                        },
                        "$$this.subMessages"
                      ]
                    }
                  }
                ]
              }
            }
          },
          {
            $concatArrays: [
              { $ifNull: ["$messages", []] },
              [
                {
                  from: from,
                  subMessages: [subMessage]
                }
              ]
            ]
          }
        ]
      }
    }
  }],
  { upsert: true }
)