#mongodb
#mongodb
Вопрос:
Мне пришлось изменить одно из полей моей коллекции в MongoDB с объекта на массив объектов, содержащий много данных. Новые документы вставляются без каких-либо проблем, но при попытке получить старые данные они никогда не сопоставляются с исходным DTO правильно и приводят к ошибкам.
тема — это поле, которое было изменено в коллекции Students.
Мне было интересно, есть ли какой-нибудь способ обновить все записи, чтобы все они имели один и тот же тип данных, без потери каких-либо данных.
Старая версия Student:
{
"_id": "5fb2ae251373a76ae58945df",
"isActive": true,
"details": {
"picture": "http://placehold.it/32x32",
"age": 17,
"eyeColor": "green",
"name": "Vasquez Sparks",
"gender": "male",
"email": "vasquezsparks@orbalix.com",
"phone": " 1 (962) 512-3196",
"address": "619 Emerald Street, Nutrioso, Georgia, 6576"
},
"subject":
{
"id": 0,
"name": "math",
"module": {
"name": "Advanced",
"semester": "second"
}
}
}
Это необходимо обновить до новой версии следующим образом:
{
"_id": "5fb2ae251373a76ae58945df",
"isActive": true,
"details": {
"picture": "http://placehold.it/32x32",
"age": 17,
"eyeColor": "green",
"name": "Vasquez Sparks",
"gender": "male",
"email": "vasquezsparks@orbalix.com",
"phone": " 1 (962) 512-3196",
"address": "619 Emerald Street, Nutrioso, Georgia, 6576"
},
"subject": [
{
"id": 0,
"name": "math",
"module": {
"name": "Advanced",
"semester": "second"
}
},
{
"id": 1,
"name": "history",
"module": {
"name": "Basic",
"semester": "first"
}
},
{
"id": 2,
"name": "English",
"module": {
"name": "Basic",
"semester": "second"
}
}
]
}
Я понимаю, что может быть способ переименовать старую коллекцию, создать новую и вставить данные на основе старой в новую. Мне было интересно найти какой-нибудь прямой путь.
Комментарии:
1. Здесь что-то не так.
student: ["idDetails":{...}
недопустимый объект. Вы имеете в видуstudent: [ {"idDetails": {...} } ]
? Я думаю, что форма, которую вы, возможно, пытаетесь использовать, больше похожа на эту:student: { idDetails: { ... }, subject: [ {modulefld1:val, modulefl2:val}, {mf1:val, mf2:val} ] }
2. Вы можете нарезать массив от первого до последнего объекта, или фильтр тоже может работать. Это может быть легко в зависимости от реальной структуры. Но нам нужно больше данных, мой друг
3. можете ли вы опубликовать образец документа из коллекции?
4. Извините за опечатку ранее, я обновил образец документа выше, обратите внимание, что в модуле есть много вложенных вложенных документов (полей), пропустил их, чтобы сделать его коротким здесь. @BuzzMoschetti; @Minsky; @wak786
Ответ №1:
Цель состоит в том, чтобы превратиться subject
в массив из 1, если он еще не является массивом, в противном случае оставьте его в покое. Это поможет:
update args are (predicate, actions, options).
db.foo.update(
// Match only those docs where subject is an object (i.e. not turned into array):
{$expr: {$eq:[{$type:"$subject"},"object"]}},
// Actions: set subject to be an array containing $subject. You MUST use the pipeline version
// of the update actions to correctly substitute $subject in the expression!
[ {$set: {subject: ["$subject"] }} ],
// Do this for ALL matches, not just first:
{multi:true});
Вы можете запускать этот конвертер снова и снова, потому что он будет игнорировать преобразованные документы.
Если цель состоит в том, чтобы преобразовать и добавить несколько новых объектов, сохранив первый, тогда мы можем настроить дополнительные объекты и объединить их в один массив следующим образом:
var mmm = [ {id:8, name:"CORN"}, {id:9, name:"DOG"} ];
rc = db.foo.update({$expr: {$eq:[{$type:"$subject"},"object"]}},
[ {$set: {subject: {$concatArrays: [["$subject"], mmm]} }} ],
{multi:true});
Комментарии:
1. Огромное спасибо