Добавление нескольких полей в массив, содержащий объекты

#arrays #mongodb #mongodb-query

#массивы #mongodb #mongodb-запрос

Вопрос:

Я пытаюсь обновить объект в массив в MongoDB.
Вот мои документы :

 > db.devis.insert({id:1,obj:[{'code':'A'},{'code':'B'}]})  
> db.devis.insert({id:2,obj:[{'code':'C'},{'code':'D'}]})  

> db.devis.find()
[
  {
    id: 1,
    obj: [ { code: 'A' }, { code: 'B' } ]
  },
  {
    id: 2,
    obj: [ { code: 'C'}, { code: 'D' } ]
  }
]
  

Я выбираю документ с кодом ‘B’.
Я могу добавить одно поле с помощью этой команды :

 > db.devis.update({'obj.code':'B'},{$set: {'obj.$.a':'a'}})  

# Result
{
  id: 1,
  obj: [ { code: 'A'}, { code: 'B', a: 'a'} ]
}
  

Теперь я хочу добавить несколько полей :

 > var = {'foo':'foo', 'bar':'bar'}
> db.devis.update({'obj.code':'B'},{$set: {'obj.$': var}})

# Result
{
  id: 1,
  obj: [ { code: 'A'}, { foo: 'foo', bar: 'bar'} ]
}

# What I want
{
  id: 1,
  obj: [ { code: 'A'}, { code: 'B', foo: 'foo', bar: 'bar'} ]
}
  

Объект перезаписывается.
Можно вставить в него несколько полей из переменной?

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

1. Ясность: вы хотите сохранить code , но избавиться a и добавить foo и bar ?

2. Нет a , это был просто пример добавления одного поля, @J.F. ответил именно на то, что я искал.

Ответ №1:

Проблема здесь в том, что вы устанавливаете весь объект.

Когда вы это делаете {$set: {obj.$:{yourObject}}} , вы сообщаете mongo: «Установите весь объект obj в качестве объекта, который я передал».

Посмотрите на этот пример

Объект с code : B является полностью новым, потому что ваш $ оператор указывает на объект и $set помещает новый объект в эту позицию.

Вам нужно это:

 db.collection.update({
  "obj.code": "B"
},
{
  "$set": {
    "obj.$.foo": "bar",
    "obj.$.foo2": "bar2"
  }
})
  

В этом случае ваш $set оператор использует $ оператор для обновления поля в объект, а не сам объект.
Таким образом, вы сообщаете mongo: «Поместите в найденный вами объект переменную с именем ‘foo’ со значением’bar’ и другую переменную ‘foo2’ со значением’bar2′»

Надеюсь, я хорошо объяснил разницу между двумя запросами.

Итак, не проверено, но с помощью:

 var = {'obj.$.foo':'foo', 'obj.$.bar':'bar'}
db.devis.update({'obj.code':'B'},{$set: var})
  

Должно работать.

Пример здесь