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")
};
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")
};
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")
};
Su consulta final sería,
- marque solo
to
condición en consulta - actualizar parte, verificar la condición,
- si
from
encontrado enmessages
matriz entonces:$map
para iterar bucle demessages
matriz y verifique la condición sifrom
encontrado y luego concatenar lossubMessages
actuales matriz con nueva entradasubMessage
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
- si
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 }
)