2013-07-02 83 views
2

我想從mysql導入一個表到mongodb直接沒有任何架構更改。mongodb nodejs多個插入問題

我寫了一個小節點腳本,我的問題是我實現它的方式。

也許我在循環中使用mongo db插入限制時遇到了一些限制。 我認爲這個問題不會發生,如果它是反向的(可能不是!)

所以這裏的東西。 mysql表中的行超過100,000,但是當循環命中超過30000時,插入的項目數量會減少。

所以我們假設在使用下面提到的腳本完成導入後,如果mysql表中有100,000個項目,那麼我最多隻能得到37000左右。

我強烈的懷疑是在節點腳本/節點mongodb連接器,或者腳本中的一些錯誤或最後在mongodb併發db插入限制。

我粘貼下面的腳本。 希望我能解決它。

感謝,

var http = require('http'), 
    mysql = require('mysql'), 
    mongo = require('mongodb').MongoClient, 
    format = require('util').format; 
var connection = mysql.createConnection({ 
    user: "xxx", 
    password: "xxx", 
    database: "mydb" 
}); 

connection.connect(); 
var query = "select * from mytable"; 
var mysqlrows = ''; 
connection.query(query, function(err,rows,fields){ 
    if(err) throw err; 

    console.log(rows.length+'rows found.'); 

    mongo.connect('mongodb://root:[email protected]:27017/mydb', function(err, db){ 
    if (err) 
     throw err; 

    var collection = db.collection('mytable'); 
    for(var i=0; i<rows.length;i++) 
    { 
     //console.log(JSON.stringify(rows[i])); 

     (function(i){ 
     collection.insert(rows[i],function(err,docs){}); 
     console.log(i); 
     })(i); 
    } 

    db.close();   
    });  
}); 
connection.end(); 
+0

'insert'可以接受一系列文檔;你是否嘗試過直接將'rows'傳遞給'insert'而不是一個一個的? – JohnnyHK

+0

感謝您的提示,我試圖刪除循環,然後嘗試插入整個「行」數組本身。它的確如你所說的那樣工作,但在這裏又出現了一個問題。如果「rows」數組的計數小於1150,它可以完美地工作,但是如果根據我的測試,行數大於1200左右,它會再次失敗。在將大量行同時插入到mongdb的方法中有些問題非常嚴重。這裏我再次懷疑某種mongodb多重插入限制。但是這在mongo db limits文檔中沒有提及。 [http://docs.mongodb.org/manual/reference/limits/] –

回答

0

要確保你從MySQL獲得的所有數據,試圖訪問的最後一排。如果你能得到它,使用mongodb的標誌w和j來確保每個調用在移到下一個之前插入數據。使用w和j標誌,您應該考慮使用和array在每個調用中插入多行來插入多個數據。

+0

感謝@innospg,mysql確實返回了所有100,000行,因爲它已由此行確認'console.log(rows.length +'rows found。')。 );'在腳本中。你在說什麼w&j旗幟?這是關於我正在使用的nodejs驅動程序的具體情況? –

+0

w和j是mongodb上一版本中的寫入關注參數。要調試您的代碼,請將安全選項設置爲true並檢查回調函數的參數err。 – innoSPG

+0

謝謝我猜mongodb節點驅動器插入選項'safe:true'與'w:1'相同。同時設置'j:1'選項,即啓用日誌功能,即使mongod進程失敗,寫操作也會安全地自動設置'w:1'標誌。對於我的情況'j:1'標誌不是一個問題,它是一個小的導入腳本,所有項目的計數都記錄在腳本本身中。我認爲'j:1'選項應該始終適用於生產插入使用。 –

2

問題在於,在通過db.close();調用關閉與MongoDb的連接之前,您並未等待insert操作完成。您需要跟蹤未完成的異步請求,然後在全部完成後才調用db.close();

+0

感謝隊友,看起來像是這樣,剛剛從代碼中移除了'db.close()'&'connection.end()'並且它在一回閤中都能正常工作。但是我會用最終代碼來更新這個線程,它將使用這個概念,但仍然關閉所有的連接,以便解決方案變成最終的。 –

+0

我發現使用['async.series'](https://github.com/caolan/async)在管理數據庫更新操作方面很有幫助,特別是在查看了這個[answer](http://stackoverflow.com/a/ 18341176/549155)from [freakish](http://stackoverflow.com/users/645551/freakish) – mjmoody383