sql >> Database >  >> NoSQL >> MongoDB

mangoest update array of voeg toe aan de array

Het grootste probleem is dat findOneAndUpdate doet precies wat de naam doet vermoeden. Het voert een find uit met behulp van het meegeleverde filter, en als er een overeenkomst wordt gevonden, worden de updates toegepast op het eerste overeenkomende document.

Als de collectie alleen dit document bevat:

[
    {
        "_id": "5e90ae0e0ed9974174e92826",
        "payments": [
            {
                "year_month": "2020_02",
                "status": false
            }
        ]
    }
]

Het eerste vondstgedeelte is in wezen

.find({
        _id: '5e90ae0e0ed9974174e92826',
        payments: { $elemMatch: { year_month: '2020_03' }}
})

Dit komt met niets overeen, en aangezien upsert is ingesteld op true, probeert fineOneAndUpdate een gloednieuw document te maken. Zelfs als het een array zou kunnen maken van een ongeëvenaarde positionele operator, zou het document dat het zou proberen toe te voegen zijn:

 {
        "_id": "5e90ae0e0ed9974174e92826",
        "payments": [
            {
                "year_month": "2020_03",
                "status": false
            }
        ]
}

Dit is niet correct en kan niet worden ingevoegd vanwege dubbele _id waarde toch.

Als u MongoDB 4.2 gebruikt, kunt u een aggregatiepijplijn gebruiken als tweede argument voor findAndUpdate om de array te controleren op het element waarin u geïnteresseerd bent en het toe te voegen als het ontbreekt.

Een niet erg mooie methode is hieronder. De findOneAndUpdate komt overeen met de _id en de pijplijn zal:
- controleren of een element in de array overeenkomt met de gewenste year_month
- Zo ja, $reduceer de array om het statusveld in dat element bij te werken
- Zo niet, voeg dan een nieuw element toe
- Wijs het resultaat toe aan payments

.findOneAndUpdate(
    { "_id": "5e90ae0e0ed9974174e92826" },
    [{$set: {
         payments: {$cond:[
                 {$gt:[
                       {$size:
                             {$filter:{
                                  input:"$payments", 
                                  cond:{$eq:["$$this.year_month","2020_03"]}
                       }}},
                       1
                  ]},
                  {$reduce:{
                        input:"$payments",
                        initialValue:[],
                        in:{$concatArrays:[
                                  "$$value",
                                  [{$cond:[
                                       {$eq:["$$this.j",3]},
                                       {$mergeObjects:["$$this",{status:true}]},
                                       "$$this"
                                  ]}]
                        ]}
                  }},
                  {$concatArrays:[
                       "$payments",
                       [{year_month:"2020_03", status:true}]
                  ]}
          ]}
     }}]
)


  1. NoSQL versus SQL wanneer schaalbaarheid niet relevant is

  2. Heel raar Mongoose / MongoDB-probleem bij het uitvoeren van de MEAN-site op Openshift

  3. MongoDB $ slice

  4. Mongoose / MongoDB $addToSet-functionaliteit gebruiken op een reeks objecten