2016-06-13 1 views
1

Итак, у меня есть база данных MongoDB с миллионами записей в нескольких коллекциях. Вот (сильно упрощенный) пример некоторых записей ... документыmongodb: глобально заменить все ссылки на один ObjectID другим?

Коллекция A выглядит следующим образом:

{ 
    _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) в коллекции A. И каждый из них упоминается сотни тысяч раз в сборнике B.

Однако экземпляры B не ссылаются на два экземпляра разные коллекции. Документы, дублирующие друг друга.

Итак, что мне нужно сделать, чтобы исправить это: Для каждой пары дубликатов в коллекции А с _id «s ObjectId(X) и ObjectId(Y), заменить все вхождения ObjectId(Y) с ObjectId(X) для всех документов в коллекции В.

Если бы я имел дело с сырыми файлами JSON, я бы просто выполнил замену строк и покончил с этим.

Есть ли простой способ сделать это в оболочке mongo, просто используя одну команду для каждого из дубликатов Collection A?

+0

Я полагаю, что человек является дубликатом - у вас есть возможность выбора дубликатов (это на поле идентификатора или других метаданных?) – profesor79

+0

Это всего лишь несколько конкретных дубликатов, вызванных ошибками ввода вручную. Легкий способ заменить все ссылки на один из них за раз сделал бы трюк. – DanM

ответ

0

siplest способ сделать, чтобы получить эту работу, это использовать 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 
} 
+0

OK; надеялся, что есть простая команда, которая просто заменит каждый отдельный экземпляр, но похоже, что мне нужно перебирать вручную. – DanM