MongoDB: обновить вложенное значение в коллекции на основе существующего значения поля - PullRequest
0 голосов
/ 17 февраля 2019

Я хочу обновить вложенные _ids для всей коллекции, ЕСЛИ они имеют строку типа.

Если у меня есть объект, который выглядит следующим образом ...

user : {
    _id: ObjectId('234wer234wer234wer'),
    occupation: 'Reader',
    books_read: [
        {
           title: "Best book ever",
            _id: "123qwe234wer345ert456rty"
        },
        {
           title: "Worst book ever",
            _id: "223qwe234wer345ert456rty"
        },
        {
           title: "A Tail of Two Cities",
            _id: ObjectId("323qwe234wer345ert456rty")
        }
    ]
}

и я хочуизменить тип _Ids со строки на ObjectId

как бы я это сделал .??

Я делал "это" в прошлом ... Но это работает на NON-вложенный элемент - мне нужно изменить вложенное значение

 db.getCollection('users')
.find({
  $or: [
    {occupation:{$exists:false}},
    {occupation:{$eq:null}}
  ]
})
.forEach(function (record) {
  record.occupation = 'Reader';
  db.users.save(record);
});

Любая помощь - я стараюсь избегать написания серии циклов на сервере приложений для выполнения вызовов db - поэтому я надеюсь на что-то прямо в 'монго '

1 Ответ

0 голосов
/ 17 февраля 2019

Нет способа выполнять (не $rename) операции обновления документа при обращении к существующим полям - MongoDB: Обновление документов с использованием данных из того же документа

Итак, вам нужно написать скрипт (аналогичный тому, который вы опубликовали с find & each), чтобы воссоздать эти документы с правильным типом _id.Чтобы найти поддокументы для обновления, вы можете использовать оператор $type.Запрос типа db.coll.find({nestedField._id: {$type: 'string' }}) должен найти все полные документы с плохими вложенными документами, или вы можете выполнить запрос агрегации с помощью $match & $unwind, чтобы получить только вложенные документы

db.coll.aggregate([
  { $match: {'nestedField._id': {$type: 'string' }}}, // limiting to documents that have any bad subdocuments
  { $unwind: '$nestedField'}, // creating a separate document in the pipeline for each entry in the array
  { $match: {'nestedField._id': {$type: 'string' }}}, // limiting to only the subdocuments that have bad fields
  { $project: { nestedId: 'nestedField._id' }} // output will be: {_id: documentedId, nestedId }
])

Я пытаюсь избежать написания серии циклов на сервере приложений для выполнения вызовов db - поэтому я надеюсь на что-то прямо в 'mongo'

You can запускайте js-код прямо на mongo, чтобы избежать вызовов API, но я не думаю, что есть какой-либо способ избежать циклического обхода документов.

...