MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

$push con posizionale ($) in upsert non riesce

Upsert non funzionerà nei documenti nidificati nella query di aggiornamento,

Puoi provare un aggiornamento complesso con una query di aggregazione per gestire i tuoi casi se vuoi farlo in un'unica query,

Prendiamo un input di esempio e vediamo l'esempio per quanto riguarda i casi,

Caso 1: Se specificato messages.from il campo esiste in messages matrice

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

Parco giochi

Caso 2: Se messages.from il campo non esiste nell'array

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

Parco giochi

Caso 3: Se il documento non esiste

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

Parco giochi

La tua domanda finale sarebbe,

  • controlla solo da to condizione in questione
  • aggiorna parte, verifica la condizione,
    • se from trovato in messages array quindi:
      • $map per iterare il ciclo di messages array e verifica la condizione se from trovato quindi concat subMessages correnti array con nuovo input subMessage usando $concatArrays , $mergeObjects per unire l'oggetto corrente con l'oggetto aggiornato
    • altrimenti da non trovato, quindi concatena la nuova matrice di oggetti del messaggio nei messages correnti array usando $cocnatArrays
  • upsert: true , per inserire nuovo documento se non presente nella collezione
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 }
)