Upsert funktioniert nicht in verschachtelten Dokumenten in Aktualisierungsabfragen,
Sie können eine komplexe Aktualisierung mit einer Aggregationsabfrage versuchen, um Ihre Fälle zu bearbeiten, wenn Sie dies in einer einzigen Abfrage tun möchten,
Nehmen wir eine Beispieleingabe und sehen uns das Beispiel fallweise an,
Fall 1: Falls angegeben messages.from
Feld existiert in messages
Array
var to = "111";
var from = "222";
var subMessage = {
message: "test",
date: ISODate("2021-06-29T15:57:53.975Z")
};
Fall 2: Wenn messages.from
Feld existiert nicht im Array
var to = "111";
var from = "333";
var subMessage = {
message: "test2",
date: ISODate("2021-06-29T15:57:53.975Z")
};
Fall 3: Wenn das Dokument nicht existiert
var to = "111";
var from = "333";
var subMessage = {
message: "test2",
date: ISODate("2021-06-29T15:57:53.975Z")
};
Ihre letzte Abfrage wäre,
- nur
to
markieren Bedingung in Abfrage - Teil aktualisieren, Zustand prüfen,
- wenn
from
gefunden inmessages
Array dann:$map
Schleife vonmessages
durchlaufen Array und Bedingung prüfen, wennfrom
gefunden dann aktuellesubMessages
zusammenfügen Array mit neuer EingabesubMessage
mit$concatArrays
,$mergeObjects
um das aktuelle Objekt mit dem aktualisierten Objekt zusammenzuführen
- else from not found then concat new message object array in current
messages
Array mit$cocnatArrays
- wenn
upsert: true
, um ein neues Dokument einzufügen, wenn es nicht in der Sammlung gefunden wird
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 }
)