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
tocondición en consulta - actualizar parte, verificar la condición,
- si
fromencontrado enmessagesmatriz entonces:$mappara iterar bucle demessagesmatriz y verifique la condición sifromencontrado y luego concatenar lossubMessagesactuales matriz con nueva entradasubMessageusando$concatArrays,$mergeObjectspara fusionar el objeto actual con el objeto actualizado
- si no no encontrado, entonces concatene la nueva matriz de objetos de mensaje en los
messagesactuales 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 }
)