mongodb: глобально заменить все ссылки на один ObjectID с другим?
Итак, у меня есть база данных MongoDB с миллионами записей в нескольких коллекциях. Вот (очень упрощенный) пример некоторых записей...
Сборник документов выглядит так:
{
_id: ObjectID(....)
name: "Hubert Humphrey"
}
Документы коллекции B выглядят так:
{
_id: ObjectID(....)
ReferenceSummary: [
{
person: ObjectID(<some-ID-from-Collection-A>)
count: 312
},
{
person: ObjectID(<some-other-ID-from-Collection-A>)
count: 42
},
...
],
TopPeople: [ ObjectID(<another-ID-from-Collection-A>), ObjectID(<yet-another-ID-from-Collection-A>), ...]
}
Теперь вот проблема. Мы поняли, что у нас есть несколько дубликатов (только 3 или 4) в Коллекции А. И на каждую из них сотни тысяч раз ссылаются в Коллекции Б.
Однако не существует случаев, когда данный документ Коллекции B ссылается на два разных документа Коллекции А, которые являются дубликатами друг друга.
Итак, что мне нужно сделать, чтобы это исправить: Для каждой пары дубликатов в Коллекции А, с _id
"s ObjectId(X)
а также ObjectId(Y)
замените все вхождения ObjectId(Y)
с ObjectId(X)
для всех документов в коллекции B.
Если бы я имел дело с необработанными файлами JSON, я просто сделал бы подстановку строк и покончил бы с этим.
Есть ли простой способ сделать это в оболочке Монго, просто используя одну команду для каждого дубликата Коллекции А?
1 ответ
Самый простой способ выполнить эту работу - использовать forEach
петля
var ids = [id1, id2, ...., idN];
var idsToReplace = [id1TR, id2TR, ...., IdNTR];
var aLenght = ids.lenght;
for (var i = o; i < aLenght; i++) {
db.collectionA.find({
_id : ids[i]
}).forEach(function (doc) {
doc.fieldA = idsToReplace[i];
// if we habve an array entry we need to iterate thru it
var arrayXLenght = doc.arrayX.lenght;
for (var j = 0; j < arrayXLenght; j++) {
if (doc.arrayX[j].field === ids[i]) {
doc.arrayX[j].field = idsToReplace[i];
}
}
prinjson(doc); //verify changes
//doc.save() //uncoment when you wil be assured that changes are ok
})
// same thing with other collection
}