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

актуализира двуслоен вложен обект въз основа на идентификатора

Всъщност можете да решите проблема си с актуализацията метод, но трябва да го направите по различен начин, ако използвате MongoDB 4.2 или по-нова версия. Вторият параметър може да бъде $set операция, която искате да изпълните, или aggregation тръбопровод. Използвайки по-късно, имате повече свобода при оформяне на данните. Това е начинът, по който можете да разрешите проблема си, ще разбия след:

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

Първо използвайте актуализацията метод, предаващ три параметъра:

  • Филтриране на заявка
  • Тръбопровод за агрегиране
  • Опции. Тук току-що използвах new: true за да върнете актуализирания документ и да улесните тестването му.

Това е структурата:

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

Вътре в тръбопровода се нуждаем само от един етап, $set за да замените свойството advanced с масив, който ще създадем.

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

Първо картографираме advanced масив, за да можете да картографирате масива с вложени карти след:

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

Използваме променливата, която декларирахме на първата карта и която съдържа текущия елемент от разширения масив, който се картографира ( adv ), за достъп и картографиране на вложения масив „карти“ ( $$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",
          }
        }     
      } 
    }
  }
]
...

Накрая проверяваме дали текущият идентификатор на картата е равен на търсения идентификатор $eq: [ "$$advcard.id", "main-2-1" ] и върнете новата карта, ако съвпада, или текущата карта:

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

...

Ето работещ пример за описаното:https://mongoplayground.net/p/xivZGNeD8ng




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Как да намерите разликата в часовете между две дати в mongodb

  2. Как да премахнете елемента на масива в mongodb?

  3. Изтрийте всички символи, различни от utf-8 от низа

  4. Едновременната актуализация на MongoDB на същия документ не се държи атомарно

  5. Изтриването на (издърпване) на документ в масив от Mongoose не работи с ObjectID