MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Aktualisieren Sie das zweischichtige verschachtelte Objekt basierend auf der ID

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:

abbilden zu können
...
[
  {
    $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