sql >> Databáze >  >> NoSQL >> MongoDB

mongoose aktualizovat pole nebo přidat do pole

Hlavním problémem je, že findOneAndUpdate dělá přesně to, co jeho název napovídá. Provede find pomocí poskytnutého filtru, a pokud je nalezena shoda, použije aktualizace na první odpovídající dokument.

Pokud sbírka obsahuje pouze tento dokument:

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

Počáteční část hledání je v podstatě

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

Tomu neodpovídá nic, a protože je upsert nastaveno na true, fineOneAndUpdate se pokusí vytvořit zcela nový dokument. I kdyby byl schopen vytvořit pole z neodpovídajícího pozičního operátoru, dokument, který by se snažil přidat, by byl:

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

Toto není správné a vložení se nezdařilo z důvodu duplicitního _id hodnotu.

Pokud používáte MongoDB 4.2, můžete použít agregační kanál jako druhý argument pro findAndUpdate zkontrolujte pole prvku, který vás zajímá, a přidejte jej, pokud chybí.

Jedna nepříliš pěkná metoda je níže. FindOneAndUpdate bude odpovídat _id a kanál:
- zkontroluje, zda některý prvek v poli odpovídá požadovanému year_month
- Pokud ano, $redukujte pole a aktualizujte stavové pole v tomto prvku
- Pokud ne, přidejte nový prvek
- Přiřaďte výsledek zpět k 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. Unikátní index v mongoose nefunguje

  2. Stavová sada Kubernetes s trvalým svazkem NFS

  3. Jak v Mongodb zkontroluji, zda jsou všechny dokumenty jedinečné pro určitou hodnotu?

  4. Podporuje AWS DocumentDB spojení 3+ sbírek v jediném dotazu?