2011-11-29 59 views
0

我有一個大的數據集,有時相互交叉引用的文檔,有時不。在基於這些交叉引用映射精簡之前,我必須將交叉引用的數組設置爲交叉引用中的每個值都相同。MongoDB:函數來鞏固陣列

我用這個在shell功能來鞏固這些陣列:

function fixArray2() { 
var counter = 0; 
// I only want the xref for each field, I don't even want the id 
var cursor = db.catalog.find({}, {xref: true, _id: false}); 

// I don't want to init this inside the loop, worried about memory leaks 
var consolidatedArray = []; 
while (cursor.hasNext()) { 
    var xref1 = cursor.next().xref; 
    // first pass: create a consolidated array when the cross references match 
    var limitedCursor1 = db.catalog.find({"name":{$in:xref1}}); 
    while (limitedCursor1.hasNext()) { 
     var doc1 = limitedCursor1.next(); 
     consolidatedArray = consolidatedArray.concat(doc1.xref); 
    } 
    consolidatedArray = consolidatedArray.unique(); 
    // now that we have the consolidated array, reset the xref field of the object to it 
    for (var i=0; i<consolidatedArray.length; i++) { 
     db.catalog.update({name:consolidatedArray[i]},{$set:{xref: consolidatedArray}},false, true); 
    } 

    consolidatedArray.length = 0; 

    counter++; 
    if (counter % 1000 == 0) { 
     print("Processed " + counter + " documents."); 
    } 
} 

}

它的工作原理,但我必須相當頻繁運行它。任何人都可以改進?

回答

1

如果您在將文檔寫入集合時事先進行了這項工作,那麼您可能可以避免在稍後執行此工作的地圖縮小範圍。

因此,獲取應交叉引用的文檔列表,並在插入時將其與文檔一起寫入。當文檔被刪除或不再引用另一個文檔時,根據需要進行更新。

+0

我從中央歸檔中檢索數據,並通過mongoimport進行導入,因此預處理數據會有點困難。 – Jason

+0

我可以按原樣導入它,然後編寫一些代碼,以便在導入這些結果並將結果存儲在另一個集合中之後以我想要的形式得到它。 –

+0

標記爲已接受。不是我喜歡這樣做的方式,但仍然是一個很好的答案。 – Jason