Mit dem Update können Sie Ihr Problem tatsächlich beheben -Methode, aber Sie müssen es anders machen, wenn Sie MongoDB 4.2 oder höher verwenden. Der zweite Parameter kann der $set
sein Vorgang, den Sie ausführen möchten, oder eine aggregation
Pipeline. Mit letzterem haben Sie mehr Freiheit bei der Gestaltung der Daten. So können Sie Ihr Problem lösen, ich werde nachher aufschlüsseln:
db.collection.update({
"cards.advanced.unit": 2
},
[
{
$set: {
"cards.advanced": {
$map: {
input: "$cards.advanced",
as: "adv",
in: {
cards: {
$map: {
input: "$$adv.cards",
as: "advcard",
in: {
$cond: [
{
$eq: [
"$$advcard.id",
"main-2-1"
]
},
{
title: "this is a NEW updated card",
id: "$$advcard.id"
},
"$$advcard"
]
}
}
},
unit: "$$adv.unit"
}
}
}
}
}
],
{
new: true,
});
Verwenden Sie zuerst das Update Methode, die drei Parameter übergibt:
- Filterabfrage
- Aggregationspipeline
- Optionen. Hier habe ich einfach
new: true
verwendet um das aktualisierte Dokument zurückzugeben und das Testen zu erleichtern.
Dies ist die Struktur:
db.collection.update({
"cards.advanced.unit": 2
},
[
// Pipeline
],
{
new: true,
});
Innerhalb der Pipeline benötigen wir nur eine Stufe, den $set
um die Eigenschaft advanced
zu ersetzen mit einem Array, das wir erstellen werden.
...
[
{
$set: {
"cards.advanced": {
// Our first map
}
}
}
]
...
Wir mappen zuerst den advanced
Array, um das verschachtelte Karten-Array nach:
...
[
{
$set: {
"cards.advanced": {
$map: {
input: "$cards.advanced",
as: "adv",
in: {
// Here we will map the nested array
}
}
}
}
}
]
...
Wir verwenden die Variable, die wir auf der ersten Zuordnung deklariert haben und die das aktuelle zugeordnete Element des erweiterten Arrays enthält ( adv
), um auf das verschachtelte „Karten“-Array ( $$adv.cards
) zuzugreifen und es zuzuordnen ):
...
[
{
$set: {
"cards.advanced": {
$map: {
input: "$cards.advanced",
as: "adv",
in: {
cards: {
$map: {
input: "$$adv.cards",
as: "advcard",
in: {
// We place our condition to check for the chosen card here
}
}
},
unit: "$$adv.unit",
}
}
}
}
}
]
...
Zuletzt prüfen wir, ob die aktuelle Karten-ID mit der gesuchten ID übereinstimmt $eq: [ "$$advcard.id", "main-2-1" ]
und geben Sie die neue Karte zurück, wenn sie passt, oder die aktuelle Karte:
...
{
$cond: [
{
$eq: [
"$$advcard.id",
"main-2-1"
]
},
{
title: "this is a NEW updated card",
id: "$$advcard"
},
"$$advcard"
]
}
...
Hier ist ein Arbeitsbeispiel für die Beschreibung:https://mongoplayground.net/p/xivZGNeD8ng