Upsert fungerar inte i kapslade dokument i uppdateringsfråga,
Du kan prova en komplex uppdatering med en aggregeringsfråga för att hantera dina ärenden om du vill göra det i en enda fråga,
Låt oss ta ett exempel på input och se exempel från fall,
Fall 1: Om specificerat messages.from
fältet finns i messages
array
var to = "111";
var from = "222";
var subMessage = {
message: "test",
date: ISODate("2021-06-29T15:57:53.975Z")
};
Fall 2: Om messages.from
fältet finns inte i array
var to = "111";
var from = "333";
var subMessage = {
message: "test2",
date: ISODate("2021-06-29T15:57:53.975Z")
};
Fall 3: Om dokumentet inte finns
var to = "111";
var from = "333";
var subMessage = {
message: "test2",
date: ISODate("2021-06-29T15:57:53.975Z")
};
Din sista fråga skulle vara,
- markera endast
to
skick i fråga - uppdatera delen, kontrollera skicket,
- om
from
finns imessages
array sedan:$map
att upprepa loop avmessages
array och kontrollera skick omfrom
hittade sedan sammanfoga aktuellasubMessages
array med ny ingångsubMessage
med$concatArrays
,$mergeObjects
för att slå samman aktuellt objekt med uppdaterat objekt
- annat från inte hittat och sedan sammanfoga ny meddelandeobjektmatris i nuvarande
messages
array med$cocnatArrays
- om
upsert: true
, för att infoga ett nytt dokument om det inte finns i samlingen
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 }
)