Создать массив, если он не существует, или добавить элемент к существующему

#mongodb #mongodb-query

#mongodb #mongodb-запрос

Вопрос:

Мне нужно добавить элементы к определенному подобъекту в моей коллекции. Возможно ли это сделать, используя только метод обновления, учитывая, что массив может не существовать в некоторых объектах?

Вот пример структуры:

 [
  {
    "key": 1,
    "someValue": "abc",
    "installments": [
      {
        "number": 1,
        "payments": [
          {
            "paymentNumber": 1,
            "value": 29
          },
          {
            "paymentNumber": 2,
            "value": 22
          }
        ]
      }
    ]
  },
  {
    "key": 2,
    "someValue": "xyz",
    "installments": [
      {
        "number": 1,
        "payments": [
          {
            "paymentNumber": 3,
            "value": 10
          },
          {
            "paymentNumber": 4,
            "value": 1
          },
          {
            "paymentNumber": 5,
            "value": 5
          }
        ]
      }
    ]
  }
]
  

И вот синтаксис, который я использую:

 db.collection.update({
  "installments.payments.paymentNumber": 4
},
{
  "$push": {
    "installments.payments": [
      {
        "receipts": [
          {
            "receiptNumber": 1
          }
        ]
      }
    ]
  }
})
  

Это вызывает эту ошибку:

 fail to run update: multiple write errors: [{write errors: [{Cannot create field 'payments' in element {installments: [ { number: 1.0, payments: [ { paymentNumber: 3.0, value: 10.0 }, { paymentNumber: 4.0, value: 1.0 }, { paymentNumber: 5.0, value: 5.0 } ] } ]}}]}, {<nil>}]
  

Возможно ли это?

Вот ссылка на игровую площадку Mongo

И вот ожидаемый результат:

 [
  {
    "key": 1,
    "someValue": "abc",
    "installments": [
      {
        "number": 1,
        "payments": [
          {
            "paymentNumber": 1,
            "value": 29
          },
          {
            "paymentNumber": 2,
            "value": 22
          }
        ]
      }
    ]
  },
  {
    "key": 2,
    "someValue": "xyz",
    "installments": [
      {
        "number": 1,
        "payments": [
          {
            "paymentNumber": 3,
            "value": 10
          },
          {
            "paymentNumber": 4,
            "value": 1,
            "receipts": [{
              "receiptNumber": 1
            }]
          },
          {
            "paymentNumber": 5,
            "value": 5
          }
        ]
      }
    ]
  }
]
  

Комментарии:

1. Можете ли вы опубликовать ожидаемый результат?

2. Конечно. Просто добавил его. Спасибо

Ответ №1:

Для обновления вложенных массивов отфильтрованный позиционный оператор $[идентификатор] идентифицирует элементы массива, которые соответствуют arrayFilters условиям для операции обновления.

Попробуйте выполнить следующий запрос к $push во вложенном массиве:

 db.collection.update({
  "installments.payments.paymentNumber": 4,
  
},
{
  "$push": {
    "installments.$.payments.$[payments].receipts": {
      "receiptNumber": 1
    }
  }
},
{
  "arrayFilters": [
    {
      "payments.paymentNumber": 4
    }
  ],
  multi: true
})
  

Игровая площадка MongoDB

Комментарии:

1. Это неправильно. Он должен добавить квитанции к элементу платежей с номером платежа, равным 4.

2. @JulianoNunesSilvaOliveira Я обновил ответ. Пожалуйста, проверьте

3. Если вы хотите обновить несколько документов, обязательно добавьте multi:true . Смотрите обновленный запрос

4. Я не понял, почему это обновление нескольких документов, но ваш код действительно работал для того, что мне нужно. Я проверю план выполнения, чтобы узнать, быстрее ли это, чем запрашивать элемент и после этого добавлять новый элемент.