mongodb:全局替换所有对一个ObjectID的引用?

时间:2016-06-13 17:56:51

标签: javascript mongodb mongo-shell

所以我有一个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>), ...]
}

现在问题就在于此。我们意识到我们在集合A中有一些重复项(只有3或4个)。它们在集合B中都被引用了数十万次。

但是,没有给定的Collection B文档引用两个彼此重复的不同Collection A文档的实例。

所以,我需要做的是解决这个问题:对于集合A中的每对重复项,使用_id的{​​{1}}和ObjectId(X),替换所有出现的{{ 1}}与ObjectId(Y)对于集合B中的所有文档。

如果我正在处理原始JSON文件,我只需要进行字符串替换并完成它。

有没有一种简单的方法在mongo shell中执行此操作,只需对每个Collection A重复项使用一个命令?

1 个答案:

答案 0 :(得分:0)

完成这项工作的最简单方法是使用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
}