sql >> Database teknologi >  >> NoSQL >> MongoDB

opdater to-lags indlejret objekt baseret på id'et

Du kan faktisk løse dit problem med opdateringen metode, men du skal gøre det på en anden måde, hvis du bruger MongoDB 4.2 eller nyere. Den anden parameter kan være $set handling du vil udføre eller en aggregation rørledning. Ved at bruge det senere har du større frihed til at forme dataene. Dette er måden du kan løse dit problem på, jeg vil opdele efter:

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,
  
});

Først med brug opdateringen metode, der sender tre parametre:

  • Filtreringsforespørgsel
  • Aggregation pipeline
  • Valgmuligheder. Her brugte jeg lige new: true for at returnere det opdaterede dokument og gøre det nemmere at teste.

Dette er strukturen:

db.collection.update({
  "cards.advanced.unit": 2
},
[
  // Pipeline
],
{
  new: true,
});

Inde i pipelinen har vi kun brug for et trin, $set for at erstatte egenskaben advanced med et array, vi vil skabe.

...
[
  {
    $set: {
      "cards.advanced": {
        // Our first map
      } 
    }
  }
]
...

Vi kortlægger først den advanced array for at kunne kortlægge det indlejrede kort-array efter:

...
[
  {
    $set: {
      "cards.advanced": {
        $map: {
          input: "$cards.advanced",
          as: "adv",
          in: {
            // Here we will map the nested array
          }
        }     
      } 
    }
  }
]
...

Vi bruger den variabel, vi erklærede på det første kort, og som indeholder det avancerede array, som aktuelle element bliver kortlagt ( adv ) for at få adgang til og kortlægge det indlejrede "kort"-array ( $$adv.cards ):

...
[
  {
    $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",
          }
        }     
      } 
    }
  }
]
...

Til sidst tjekker vi, om det aktuelle kort-id er lig med det id, der søges $eq: [ "$$advcard.id", "main-2-1" ] og returner det nye kort, hvis det matcher eller det nuværende kort:

...
{
  $cond: [
    {
      $eq: [
        "$$advcard.id",
        "main-2-1"
      ]
    },
    {
      title: "this is a NEW updated card",
      id: "$$advcard"
    },
    "$$advcard"
  ]
}

...

Her er et fungerende eksempel på, hvad der er beskrevet:https://mongoplayground.net/p/xivZGNeD8ng




  1. CDH 6.2-udgivelse:Hvad er nyt i HBase

  2. Sådan sletter du mange dokumenter i en partitioneret samling i Azure CosmosDB ved hjælp af MongoDB API

  3. Opdater et underdokument indeholdt i et array indeholdt i et MongoDB-dokument

  4. Hvordan håndterer MongoDB samtidige opdateringer?