MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

mongoose актуализира масива или добавя към масива

Основният проблем е, че findOneAndUpdate прави точно това, което подсказва името му. Той изпълнява find използва предоставения филтър и ако бъде намерено съвпадение, прилага актуализациите към първия съответстващ документ.

Ако колекцията съдържа само този документ:

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

Първоначалната част за намиране е по същество

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

Това не съвпада с нищо и тъй като upsert е зададено на true, fineOneAndUpdate се опитва да създаде чисто нов документ. Дори и да може да създаде масив от несъвпадащ позиционен оператор, документът, който ще се опитва да добави, ще бъде:

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

Това не е правилно и няма да може да се вмъкне поради дублиран _id стойност така или иначе.

Ако използвате MongoDB 4.2, можете да използвате тръбопровод за агрегиране като втори аргумент за findAndUpdate за да проверите масива за елемента, който ви интересува, и да го добавите, ако липсва.

Един не много красив метод е по-долу. FindOneAndUpdate ще съвпадне с _id и тръбопроводът ще:
- провери дали някой елемент в масива съвпада с желания year_month
- Ако е така, $редуцирайте масива, за да актуализирате полето за състояние в този елемент
- Ако не, добавете нов елемент
- Присвоете резултата обратно към 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. Как бихте моделирали приятелска връзка в MongoDB?

  2. Създаване на mongoose модели с машинопис - поддокументи

  3. Неуспешно свързване на Mongoose с Atlas

  4. Свързване към отдалечен mongoDB сървър

  5. Получаване на времеви печат на unix за секунди от MongoDB ISODate по време на агрегиране