2011-11-21 63 views
6

從C#文檔:MongoDB的C#collection.Save VS插入+更新

Save方法是插入和更新的組合。如果文檔的Id成員有值,則假定它是現有文檔,並在文檔上保存調用Update(設置Upsert標誌,以防萬一它實際上是新文檔)。

我在基礎類中手動創建我的ID,所有的域對象都從中繼承。所以我所有的域對象在插入到MongoDB時都有一個ID。

問題是,我應該使用collection.Save並保持我的接口簡單,否則實際上會導致Save-call(帶有Upsert標誌)的一些開銷,並且我應該爲此使用collection.Insert和Update嗎?

我在想,Save方法首先調用Update,然後發現我的新對象不存在於第一個位置,然後調用Insert。我錯了嗎?有沒有人測試過這個?

注意:我使用InsertBatch插入批量數據,所以在這種情況下大數據塊無關緊要。

編輯,跟進

我寫了一個小測試,以找出是否有標誌的Upsert調用Update有一些開銷,所以插入可能會更好。原來,他們以相同的速度運行。看到我的測試代碼如下。 MongoDbServer和IMongoDbServer是我自己的通用接口來隔離存儲設備。

IMongoDbServer server = new MongoDbServer(); 
Stopwatch sw = new Stopwatch(); 
long d1 = 0; 
long d2 = 0; 
for (int w = 0; w <= 100; w++) 
{ 
    sw.Restart(); 
    for (int i = 0; i <= 10000; i++) 
    { 
     ProductionArea area = new ProductionArea(); 
     server.Save(area); 
    } 
    sw.Stop(); 
    d1 += sw.ElapsedMilliseconds; 
    sw.Restart(); 
    for (int i = 0; i <= 10000; i++) 
    { 
     ProductionArea area = new ProductionArea(); 
     server.Insert(area); 
    } 
    sw.Stop(); 
    d2 += sw.ElapsedMilliseconds; 
} 
long a1 = d1/100; 
long a2 = d2/100; 

回答

12

的保存方法是打算讓兩趟到服務器。

啓發式是這樣的:如果保存的文檔沒有_id字段的值,則爲其生成一個值,然後調用Insert。如果要保存的文檔對於_id具有非零值,則使用Upsert標誌調用Update,在這種情況下,由服務器決定是執行Insert還是Update。

我不知道一個Upsert是否比Insert更昂貴。我懷疑他們幾乎是一樣的,真​​正重要的是,無論是單一的網絡往返。

如果您知道這是一個新文檔,您可以調用Insert。並且調用InsertBatch的方式是方式比調用許多單獨的插入更好的性能。所以絕對喜歡InsertBatch保存。