2015-11-18 61 views
1

關於隨機排序結果或隨機獲取單個記錄有許多問題和解答。答案建議添加一個隨機字段,在該字段上創建索引,然後進行隨機抽取。它看起來像:如何批量向MongoDB中的每條記錄添加一個隨機字段

db.myindex.find().forEach(function(doc) { 
    db.myindex.update({_id: doc._id}, {$set: {rand: Math.random()}}) 
}) 

這很好,但它需要幾個小時(大量和大量的數據)。它看起來像寫鎖定是有限的,這是有道理的,因爲更新是爲每個記錄發生的。我如何批量進行此操作?我試過了:

var bulk = db.myindex.initializeUnorderedBulkOp(); 
bulk.find({}).update({ $set: { rand: Math.random() } }); 
bulk.execute(); 

但是它爲每個記錄設置rand域爲相同的值!我該如何解決?

編輯:順便說一下,我需要這樣做的原因是因爲我從其他人那裏得到一個巨大的bson文件,我需要經常導入它,所以不能等待幾個小時才能更新它。

+0

可能你只是稍微等待版本3.2,那麼你可以使用'$ sample'操作符:https://docs.mongodb.org/manual/release-notes/3.2-reference/ – nickmilon

回答

1

介紹與發送到服務器的批量操作循環一次,每1000個文件,或儘可能多的修改,你可以根據64MB BSON限適合:

var bulk = db.myindex.initializeOrderedBulkOp(); 
var counter = 0; 

db.myindex.find().forEach(function(doc) { 

    bulk.find({ "_id": doc._id }).updateOne({ 
     "$set": { "rand": Math.random() } 
    }); 

    counter++; 

    if (counter % 1000 == 0) { 
     bulk.execute(); 
     bulk = db.myindex.initializeOrderedBulkOp(); 
    } 

}); 

if (counter % 1000 != 0){ 
    bulk.execute(); 
} 
0

如果集合僅僅是靜態數據,並你從其他人那裏獲得一個BSON文件,通過一個過濾器將BSON文件串流生成一個新的BSON文件可能會更快,然後你可以使用mongoimport導入這個BSON文件。

下面是我用nodeJS編寫的一個程序,它能夠以1GB/min的速度處理BSON文件。

var bson = require('bson'); 
var BSON = new bson.BSONPure.BSON(); 
var BSONStream = require('bson-stream'); 
var fs = require('fs'); 
var sb = require('stream-buffers'); 
var rs = fs.createReadStream('tweets.bson'); 
var ws = fs.createWriteStream('tweets_random.bson',{flags:'a'}); 

var writeBuffer = new sb.WritableStreamBuffer({ 
    initialSize: (1024*1024), 
    incrementAmount: (10*1024) 
});  
rs.pipe(new BSONStream()).on('data',function(obj) { 
    obj.rand = Math.random(); 
    writeBuffer.write(BSON.serialize(obj)); 
    if(writeBuffer.size()>(1024*1024)) { 
     var size = writeBuffer.size(); 
     ws.write(writeBuffer.getContents(),function() { 
      console.log("Wrote",size,"bytes"); 
      console.log("Buffer has:",writeBuffer.size(),"bytes left"); 
     }); 
    } 
}); 

如果您修改緩衝區大小/增量參數,它可能會更快。

這當然假設您有重新導入數據的奢侈。

相關問題