2016-02-19 51 views
0

我在我的應用程序中有幾個地方使用貓鼬,我需要處理併發修改。處理併發修改w/mongoose

我知道在我的所有文檔中都有一個'__v'版本。我在點回頭看這個博客的事情都是:

http://aaronheckmann.tumblr.com/post/48943525537/mongoose-v3-part-1-versioning

其中概述了使用__v領域,以防止在文檔中併發陣列修改。即:

posts.update({ _id: postId, __v: versionNumber } 
      , { $set: { 'comments.3.body': updatedText }}) 

貓鼬會以任何方式自動使用__v字段來驗證保存文檔嗎?或者你總是不得不將它添加到你的查詢語句中?

+0

'mongoose.set( 「調試」,真)'會回答你的問題要問你。並不是說我是這個過程的粉絲。測試'__v'的特定值意味着您已經從文檔中獲得了該信息,並且如果該值/版本不相同,則根本沒有辦法修改內容。這幾乎是不現實的,實際上你的應用程序不應該關心這個,或者更新應該以不同的方式來應用,比如「歷史」這樣的事情。即添加到數組。如果你設計適當的訪問模式,那麼你就不會有這樣的問題。 –

+1

從上面的代碼快速示例。您應該**從不**寫「comments.3.body',意味着在數組中的索引位置修改」body「。相反,你應該寫'.update({「_id」:postId,「comments._id」:commentId},{「$ set」:{「comments。$。body」:updatedText}})'。這樣你就不會更新除你知道你真正想要的元素以外的其他東西,也不會更新現在可能處於該位置的其他元素。 '__v'唯一幫助的是避免兩個用戶同時修改相同的註釋。但是,只允許作者進行修改會更好。 –

回答

0

審查Mongoose源代碼後,__v真的只用於arrays,該VERSION_WHERE時設置updating the array path

if ('$push' == op || '$pushAll' == op || '$addToSet' == op) { 
    self.$__.version = VERSION_INC; 
    } 
    // now handling $set, $unset 
    else if (/\.\d+\.|\.\d+$/.test(data.path)) { 
    // subpath of array 
    self.$__.version = VERSION_WHERE; 
    } 

而且每this answer

var t = Test(); 
t.name = 'hi' 
t.arr = [1, 2, 3, 4, 5, 6]; 

t.save(function (err, result) { 
    console.log(result); 
    // use Mongoose pull method on the array 
    t.arr.pull(3); 
    t.save(function(err2, result2) { 
     console.log(result2) 
    }); 
}); 

結果:

{ __v: 0, 
    name: 'hi', 
    _id: 53f59d2a6522edb12114b98c, 
    arr: [ 1, 2, 3, 4, 5, 6 ] } 
{ __v: 1, 
    name: 'hi', 
    _id: 53f59d2a6522edb12114b98c, 
    arr: [ 1, 2, 4, 5, 6 ] }