Пн go обновить несколько полей объекта, который находится внутри массива - PullRequest
1 голос
/ 17 января 2020

Используя Mon go findOneAndUpdate, я пытаюсь обновить только некоторые поля в объекте из массива объектов.

Мой объект:

mainObject:{
    _id: '123',
    array:[
        {title:'title' , name:'name', keep:'keep'},        
        {title:'title', keep:'keep'},
    ]
}

Я хочу изменить title и name для первого объекта в массиве и оставьте поле keep без изменений. Это мой самый близкий подход с использованием позиционного оператора :

// here i set dynamic arguments for query update
// sometimes i need to update only one field, sometime i need to update more fields
// also, is there a better way to do this?

let title
let name

 if (args.title) {
      title = { title: args.title };
    }
 if (args.name) {
      name= { name: args.name};
    }


db.Test.findOneAndUpdate(
        { _id: args.id, 'mainObject.array.title': args.title},
        {
          $set: {
            'mainObject.array.$[]': {
              ...title,
              ...name
              }
          }
      }
 )

эта проблема состоит в том, что он заменяет весь объект, в результате получается:

mainObject:{
    array:[
        {title:'changed' , name:'changed'},     //without keep...    :(
        {title:'title', keep:'keep'},
    ]
}

Должен ли я использовать рамки агрегации для этого?

1 Ответ

1 голос
/ 17 января 2020

Должно быть так:

db.test.findOneAndUpdate({'mainObject.array.title': 'title'},
{$set : {'mainObject.array.$.title':'changed','mainObject.array.$.name': 'changed'}})

Из вашего запроса $ обновит первый найденный элемент в массиве, который соответствует запросу фильтра, если у вас есть несколько элементов / объектов в array массива, тогда вы можете использовать $[] для обновления всех этих, давайте посмотрим на ваш запрос:

'mainObject.array.$[]': {
              ...title,
              ...name
              }

Основная проблема с вышеуказанным запросом состоит в том, что он обновит все объекты в массиве array, которые соответствуют фильтр с объектом ниже:

{
    ...title,
    ...name
}

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

...