MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

$push avec positionnel ($) dans les échecs d'upsert

Upsert ne fonctionnera pas dans les documents imbriqués dans la requête de mise à jour,

Vous pouvez essayer une mise à jour complexe avec une requête d'agrégation pour gérer vos cas si vous souhaitez le faire en une seule requête,

Prenons un exemple d'entrée et voyons l'exemple au cas par cas,

Cas 1 : Si spécifié messages.from le champ existe dans messages tableau

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

Aire de jeux

Cas 2 : Si messages.from le champ n'existe pas dans le tableau

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

Aire de jeux

Cas 3 : Si le document n'existe pas

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

Aire de jeux

Votre dernière requête serait :

  • cochez uniquement to condition dans la requête
  • mettre à jour la pièce, vérifier l'état,
    • si from trouvé dans les messages tableau alors :
      • $map pour itérer la boucle de messages tableau et vérifier la condition si from trouvé puis concat les subMessages actuels tableau avec une nouvelle entrée subMessage en utilisant $concatArrays , $mergeObjects pour fusionner l'objet courant avec l'objet mis à jour
    • else from not found then concat new message object array in current messages tableau utilisant $cocnatArrays
  • upsert: true , pour insérer un nouveau document s'il n'est pas trouvé dans la collection
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 }
)