2013-10-30 99 views
1

我通過mongo shell腳本在mongodb實例中插入大量測試記錄。爲什麼mongodb更新或插入而不是插入?

我使用批量插入性能db.messages.save(messagesBatch);

然而,蒙戈更新插入或更新數據,而不是將它的!

清潔收集後,我運行200只將一個循環,通過50.我從db.getLastErrorObj()後4批結束與51(?)的記錄,以下列報告批次:

/* 0 */ 
{ 
"n" : 0, 
"connectionId" : 166, 
"err" : null, 
"ok" : 1 
} 

/* 1 */ 
{ 
"updatedExisting" : false, 
"upserted" : ObjectId("527141c72a1ae75210d3a705"), 
"n" : 1, 
"connectionId" : 166, 
"err" : null, 
"ok" : 1 
} 

/* 2 */ 
{ 
"updatedExisting" : true, 
"n" : 1, 
"connectionId" : 166, 
"err" : null, 
"ok" : 1 
} 

/* 3 */ 
{ 
"updatedExisting" : true, 
"n" : 1, 
"connectionId" : 166, 
"err" : null, 
"ok" : 1 
} 

我插入的代碼如下:

var batchLimit = 50; 
var messagesBatch = []; 

function flushMessages() { 
print("* flushing... (" + messagesBatch.length + ")"); 
var inserted = false; // so far 
do { 
    db.messages.save(messagesBatch); 
    var errObj = db.getLastErrorObj(); 
    print(errObj); 
    if(errObj.ok && errObj.err === null) { 
     // no error, fine 
     inserted = true; 
     messagesBatch.length = 0; 
     print("* flushed. (" + messagesBatch.length + ")"); 
    } 
    else { 
     // insertion error ! 
     failedInsertions++; 
     print(errObj); 
    } 
} while(!inserted); 
} 

function addMessage(message) { 
messagesBatch.push(message); 
if(messagesBatch.length >= batchLimit) { 
    flushMessages(); 
} 
msgGenerated++; 
if(msgGenerated % 100000 == 0) 
    print("* " + msgGenerated); 
} 

有人可以明白爲什麼這個代碼是upserting而不是插入?我究竟做錯了什麼 ?

注意:當然,我插入的文檔沒有_id字段。

+0

你可以顯示一些示例消息嗎? – glomad

+0

@ithcy我寧願不要(公司數據),但他們沒有'_id'字段,儘管他們有一堆'xyzID'字段。 – Offirmo

+0

如果文檔包含一個_id字段,保存會做一個upsert。 – Martin

回答

0

它似乎來自於使用messagesBatch.length = 0;技術清空數組以準備下一批。當通過創建一個具有messagesBatch = [];的新數組來替代「重置」(排序)時,它按預期工作。

我猜插入是異步的,並且直接在數組參考文件上工作,似乎等待getLastErrorObj()不足以確保所有數據都已被寫入。這似乎是錯誤的。

空的第51條記錄來自腳本末尾的空陣列的不良系統「安全」沖洗,並且與問題無關。