MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

mangusta zaktualizuj tablicę lub dodaj do tablicy

Główny problem polega na tym, że findOneAndUpdate robi dokładnie to, co sugeruje jego nazwa. Wykonuje find używając dostarczonego filtra, a jeśli zostanie znalezione dopasowanie, zastosuje aktualizacje do pierwszego pasującego dokumentu.

Jeśli kolekcja zawiera tylko ten dokument:

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

Początkowa część wyszukiwania to zasadniczo

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

To nie pasuje do niczego, a ponieważ upsert jest ustawione na true, fineOneAndUpdate próbuje utworzyć zupełnie nowy dokument. Nawet gdyby był w stanie utworzyć tablicę z niedopasowanego operatora pozycyjnego, dokument, który próbowałby dodać, byłby:

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

To nie jest poprawne i nie udałoby się wstawić z powodu zduplikowanego _id wartość mimo wszystko.

Jeśli używasz MongoDB 4.2, możesz użyć potoku agregacji jako drugiego argumentu findAndUpdate aby sprawdzić tablicę dla elementu, który Cię interesuje i dodać go, jeśli go brakuje.

Poniżej znajduje się jedna niezbyt ładna metoda. findOneAndUpdate dopasuje _id, a potok:
- sprawdzi, czy jakikolwiek element w tablicy pasuje do żądanego rok_miesiąc
- Jeśli tak, $redukuj tablicę, aby zaktualizować pole statusu w tym elemencie
- Jeśli nie, dołącz nowy element
- Przypisz wynik z powrotem do 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. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Projekt jako zagnieżdżony dokument w wiosennym mongo

  2. mongodb stronicowania w oparciu o zakres

  3. Jak wyświetlić dowolne, schematyczne dane w HTML za pomocą node.js / mongodb

  4. Nodejs + Mongo db łączy się z bazą danych serwera za pomocą nazwy użytkownika i hasła

  5. Najłatwiejszy sposób na skopiowanie/klonowanie instancji dokumentu mangusta?