sql >> Base de Datos >  >> NoSQL >> MongoDB

$push con posicional ($) en upsert failes

Upsert no funcionará en documentos anidados en la consulta de actualización,

Puede probar una actualización compleja con una consulta de agregación para manejar sus casos si desea hacerlo en una sola consulta,

Tomemos una entrada de ejemplo y veamos el caso de ejemplo,

Caso 1: Si se especifica messages.from el campo existe en messages matriz

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

Patio de juegos

Caso 2: Si messages.from el campo no existe en la matriz

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

Patio de juegos

Caso 3: Si el documento no existe

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

Patio de juegos

Su consulta final sería,

  • marque solo to condición en consulta
  • actualizar parte, verificar la condición,
    • si from encontrado en messages matriz entonces:
      • $map para iterar bucle de messages matriz y verifique la condición si from encontrado y luego concatenar los subMessages actuales matriz con nueva entrada subMessage usando $concatArrays , $mergeObjects para fusionar el objeto actual con el objeto actualizado
    • si no no encontrado, entonces concatene la nueva matriz de objetos de mensaje en los messages actuales matriz usando $cocnatArrays
  • upsert: true , para insertar un nuevo documento si no se encuentra en la colección
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 }
)