2012-02-02 43 views
1

前提:由於缺省驅動程序以單向消息方式工作(只要不使用​​),更新語句是無害的。mongodb批量插入的微優化?或者這是一個重要的優化?

問題以下片段是在mongodb中對於大容量插入操作最好的方法嗎?是否可以摺疊第2步和第3步?

編輯:老車的形式,見下文

// step 1 : making sure the top-level document is present (an upsert in the real 
      example) 
db.test.insert({ x :1}) 

// step 2 : making sure the sub-document entry is present 
db.test.update({ x:1 }, { "$addToSet" : { "u" : { i : 1, p : 2 } } }, false) 

// step 3 : increment a integer within the subdocument document 
db.test.update({ x : 1, "u.i" : 1}, { "$inc" : { "u.$.c" : 1 } },false) 

我有一種感覺是沒有出路的操作3,自$運營商需要的查詢部分的查詢字段吸更新。 amirite? iamrite?

如果這是做事情的最佳方式,我可以在我的代碼中獲得創意,並堅持更新操作?

編輯:新形式

有我的邏輯錯誤,謝謝蓋茨。還是想摺疊如果可能的更新:d

// make sure the top-level entry exists and increase the incidence counter 
db.test.update({ x : 1 }, { $inc : { i : 1 } }, true) --1 

// implicetly creates the array 
db.test.update( { x : 1 , u : { $not : { $elemMatch : { i : 1 } } } } , 
        { $push : { u : { i : 1 , p :2 , c:0} } }) -- 2 

db.test.update({ x :1 , "u.i" : 1}, { $inc : { "u.$.c" : 1 } },false) --3 

說明:$addToSet沒有在這種情況下有用的,因爲它確實元素智能匹配,也沒有辦法表達可能是一個數組哪些元素mutable在C++中按照OO按位對比的說法

問題是毫無意義的數據模型是錯誤的。請投票結束(OP)。

回答

1

因此,首先要注意的是位置運算符$有點粗略。它有很多「陷阱」:它不適合用upserts,它隻影響第一次真正的匹配,等等。

要理解#2和#3的「摺疊」,你需要看看輸出你的命令:

db.test.insert({ x :1}) 
{ x:1 } // DB value 

db.test.update({ x:1 }, { "$addToSet" : { "u" : { i : 1, p : 2 } } }, false) 
{ x:1, u: [ {i:1,p;2} ] } // DB value 

db.test.update({ x : 1, "u.i" : 1}, { "$inc" : { "u.$.c" : 1 } },false) 
{ x:1, u: [ {i:1,p:2,c:1} ] } // DB value 

根據你提供的順序,整個事情可以被整合到一個更新中。

如果你只是想找到一起#2 &#3,那麼你擔心匹配'u.i':1u.$.c。但是這裏有一些邊緣案例需要澄清。

讓你開始文檔如下所示:

{ 
    x:1, 
u: [ 
     {i:1, p:2}, 
     {i:1, p:3} 
    ] 
} 

你從運行更新#3有什麼期望?

書面你:

{ 
    x:1, 
u: [ 
     {i:1, p:2, c:1}, 
     {i:1, p:3} 
    ] 
} 

這是正確的嗎?這是第一份文件合法嗎? (語義正確)?根據答案,這可能實際上是文檔結構的問題。

+0

你是對的,這是非法的。'c'應該是集合中的一個可變元素:/。 – 2012-02-03 09:39:53