MongoDB: скопируйте коллекцию ссылочных документов в качестве вложенных документов

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

Проблема в том, что я уже внедрил эту схему в производственную среду, где уже были созданы сотни записей. Что я хотел бы сделать, так это каким-то образом просмотреть все существующие данные и скопировать элементы в указанный ими parent_id в качестве вложенного документа.

Вот пример моей схемы:

Подборка 1 — Пользователь

_id
Name

Подборка 2 — Фото

_id
url
user_id

Есть ли быстрый способ изменить существующие документы на одну коллекцию, например:

Подборка — Пользователь

_id
Name
Photos: [...]

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

Дополнительная информация: я использую MongoHQ.com для размещения своей MongoDB.

Спасибо.


person Matthew Lucas    schedule 19.02.2013    source источник
comment
Вы должны сами позаботиться о любых миграциях схем, подобных этой, в коде. Просто обновите свою схему User, а затем выполните итерацию по своим коллекциям, чтобы обновить свои коллекции, чтобы отразить новую схему.   -  person JohnnyHK    schedule 20.02.2013


Ответы (1)


Я не знаю специфики вашей среды, но такого рода изменения обычно включают следующие шаги:

  1. Убедитесь, что ваш старый код не ругается, если в объекте User есть массив Photos.
  2. "Заморозить" приложение, чтобы не создавались новые User и Photo документы
  3. Запустите сценарий миграции, который скопирует Photo документы в папку User documents. Это должно быть довольно легко создать либо в javaScript, либо в коде приложения с помощью драйвера (см. пример ниже).
  4. Разверните новую версию приложения, которое ожидает, что Photos будет встроено в массив
  5. «Разморозить» приложение, чтобы начать создавать новые документы

Если вы не можете «заморозить/разморозить», вам нужно будет запустить дельта-скрипт после шага 4, который перенесет вновь созданные Photo документы после развертывания нового приложения.

Скрипт будет выглядеть примерно так (не проверено):

db.User.find().forEach(function (u) {
    u.Photos = new Array();
    db.Photo.find({user_id : u._id}).forEach(function (p) {
        u.Photos.push(p);
    }
    db.User.Save(u);
}
person Zaid Masud    schedule 19.02.2013
comment
Спасибо, это именно то, что я искал. Почему-то я думал, что это будет сложнее, чем это, но это определенно помогает объяснить это. - person Matthew Lucas; 20.02.2013