2011-02-18 59 views
1

比方說我們有以下的文檔結構:的MongoDB +常模併發和集合

class BlogPost 
{ 
    [MongoIdentifier] 
    public Guid Id{get;set;} 
    public string Body{get;set;} 
    .... 
} 

class Comment 
{ 
    [MongoIdentifier] 
    public Guid Id{get;set;} 
    public string Body {get;set;} 
} 

如果我們假設,多個用戶可以張貼在同一職位的意見,這將是對關係模型的最佳途徑這些之間?

如果Post有一個註釋集合,我可能會遇到併發問題,對嗎?

並且在Comment上放置FK類似的屬性似乎太相關,或者?

回答

4

基本上有兩種選擇:1.在帖子文檔中彙總註釋,或2.將帖子和註釋模型化爲文檔。

如果您彙總了評論,您應該a)在帖子上實施修訂版本號,允許您檢測競爭條件並實施樂觀合作處理,或者b)使用MongoDB修改器添加新評論 - 例如像

var posts = mongo.GetCollection<Post>(); 
var crit = new { Id = postId }; 
var mod = new { Comments = M.Push(new Comment(...)) }; 

posts.Update(crit, mod, false, false); 

如果模型後並作爲單獨的文檔註釋,處理併發可能是更容易,但你失去加載後,其意見與單一findOne命令的能力。

在我看來,(1)是迄今爲止最有趣的選擇,因爲它將帖子建模爲一個聚合對象,這正是當您將OO眼鏡放在:)上時的情況。這絕對是面向文檔的方法,而(2)類似於關係數據庫的扁平結構。

0

他們舉了一個例子說明你如何建模over on the MongoDB page on inserting - 我想你會想要一個評論集合作爲你的文章的一個屬性公開。您將給給定的Post實體添加註釋,這樣做可以避免將評論實體綁定回其父實體實體,因爲您有權質疑,它在RDBMS中是有意義的,但在NoSQL中並非如此解。就併發性而言,如果你不信任Mongo來爲你處理它,這可能是一個很大的暗示,你不應該在其上構建一個應用程序。

+0

Ofcourse當然,我不應該用我目前的知識建立一個應用程序。我試圖瞭解MongoDB是否將集合看作單個值,或者是否在檢測到併發時合併集合。 – 2011-02-18 19:28:36

+0

@Roger Alsing - http://www.mongodb.org/display/DOCS/How+does+concurrency+work進入一點,但我不完全確定。從我讀到的內容來看,這聽起來有點模糊,就像引擎蓋下面有一個信號量,會讓一條評論被添加,然後是第二條。 – 48klocs 2011-02-18 19:48:59

0

我創建了一個測試應用程序,它產生了1000個併發線程,將「評論」添加到相同的「發佈」,結果是很多評論都丟失了。

因此,MongoDB將子集合視爲單個值,但默認情況下它不合並更改。

如果我對後一個意見收集,然後我得到的併發問題,當兩個或多個用戶添加在完全相同的時間評論(不可能的,但有可能)

所以是有可能的註釋添加到post.comments集合而不更新整個post對象?

2

這是規範的NoSQL示例之一。執行此操作的標準方法是將Comments作爲BlogPost中的一組對象存儲。

爲了避免併發問題,MongoDB提供了幾個​​。特別是有幾個update modifiers與「子文件」或「子陣列」配合使用。

對於像這樣的內容「將此評論添加到帖子」,您通常會使用$push命令,該命令會將評論附加到帖子。

我看到您使用的是「NoRM」驅動程序。看起來他們支持原子命令,如by their tests。事實上,他們的測試執行「將此評論推送到博客文章」