2015-11-14 93 views
1

版本相關Ways to implement data versioning in MongoDBstructure of documents for versioning of a time series on mongodbMongoDB的:數據與搜索

我應該採取的版本時,我還需要能夠處理查詢什麼數據結構?

假設我有每個月我得到了約30文檔更改noFTEs的細節形式

{ _id: '12345-11', 
    noFTEs: 5 
} 

的8500個文件,我想存儲新的數據與前一個部分(s) ,連同日期。

這似乎導致:

{ _id: '12345-11', 
    noFTEs: { 
    '2015-10-28T00:00:00+01:00': 5, 
    '2015-1-8T00:00:00+01:00': 3 
    } 
} 

但我也希望能夠做的最近期數據搜索(例如noFTEs > 4,和元素應被視爲5,而不是3)。在那個階段,我所知道的是我想使用最新的數據,並且不知道密鑰。因此,替代將是一個數組

{ _id: '12345-11', 
    noFTEs: [ 
    {date: '2015-10-28T00:00:00+01:00', val: 5}, 
    {date: '2015-1-8T00:00:00+01:00', val: 3} 
    } 
} 

另一種方法 - 通過在下面的意見建議@thomasbormans - 將

{ _id: '12345-11', 
    versions: [ 
    {noFTEs: 5, lastModified: '2015-10-28T00:00:00+01:00', other data...}, 
    {noFTEs: 3, lastModified: '2015-1-8T00:00:00+01:00', other...} 
    } 
} 

我會很感激有關注意事項的一些見解,我需要前進行一路跳來跳去,我擔心我會產生一個對於Mongo來說工作量非常大的查詢。 (實際上,還有其他3個可合併搜索的字段,其中一個字段也可能會隨時間而發生變化。)

+0

我最近通過添加'版本'數組來實現版本控制。更新文檔時,未編輯的文檔將被複制並推送到版本數組中。因爲我的文檔有一個'lastModified'字段,所以我可以獲得所有版本的編輯日期。 –

+0

您是否可以搜索數據的最新條目 –

+0

我只查詢當前文檔,但是您可以$展開數組並執行聚合函數。 –

回答

1

要添加版本控制而不影響最新數據的可用性和訪問速度,請考慮創建兩個集合:一個具有最近的文檔,另一個在文檔的舊版本發生更改時將其歸檔。

您可以使用currentVersionCollection.findAndModify更新文件,而在一個命令也收到上述文件的以前(或新的,這取決於參數)版本。然後你只需要刪除返回的文檔的_id,加時間戳和/或版本號(當你沒有這些的話),並將其插入到檔案的收集。

通過自己的文檔也避免文件增長,防止文件爆裂16MB的文件限制時,他們得到改變很多存儲每個舊版本。

+0

當我想要查看時間序列時,是否必須將與相同_id相關的所有文檔存儲在一個文檔中? (在這種情況下這不會成爲問題。) –

+0

@SimonH當您想查看文檔的歷史記錄時,我會查詢該文檔的所有以前版本,然後按時間戳記/修訂編號對它們進行排序。當然,在過去的版本文件中有些字段說明它們屬於哪個當前文件。 – Philipp

2

當你建模NoSQL數據庫,有一些事情你需要牢記。

,首先是每個文件的大小。如果您在文檔中使用數組,請確保它不會超過每個文檔的16 Mb大小限制。

第二件事,你必須以輕鬆檢索模型的東西你的數據庫。一些「非規範化」是可以接受的,有利於速度和易於使用的應用程序。

所以如果你需要知道當前noFTE價值,你需要保持一個歷史只是審覈的目的,你可以用2個館藏去:

collection["current"] = [ 
    { 
     _id: '12345-11', 
     noFTEs: 5, 
     lastModified: '2015-10-28T00:00:00+01:00' 
    } 
] 

collection["history"] = [ 
    { _id: ...an object id... 
     source_id: '12345-11', 
     noFTEs: 5, 
     lastModified: '2015-10-28T00:00:00+01:00' 
    }, 
    { 
     _id: ...an object id... 
     source_id: '12345-11', 
     noFTEs: 3, 
     lastModified: '2015-1-8T00:00:00+01:00' 
    } 
] 

通過這樣做,你把你的最頻繁訪問記錄較小(我認爲當前版本更頻繁訪問)。這將使mongo更容易將「當前」集合保存在內存緩存中。並且文件將從磁盤中更快地檢索,因爲它們更小。

我覺得這個設計在內存優化方面是最好的。但是這個決定直接關係到你將使用什麼樣的數據。

編輯:我改變了我的原始響應,以便爲每個歷史條目創建分離的插入。在我的原始答案中,我試圖讓您的歷史記錄接近您的原始解決方案,以關注非規範化主題。但是,將歷史保存在數組中是一個糟糕的設計決定,我決定讓這個答案更完整。

的選擇,以保持分離的插入物在歷史而不是創建的陣列的很多:

1)每當改變一個文檔的尺寸(例如,在插入更多的數據到它),蒙戈可能需要將此文檔移動到磁盤的空白部分以容納較大的文檔。這樣,您最終會創建存儲空間,使您的收藏更大。

2)當你插入一個新文檔時,Mongo會根據以前的插入/更新嘗試預測它可以變得多大。這樣,如果您的歷史文檔的大小相似,則填充因子將變爲最佳。然而,當你維持增長的陣列時,這個預測不會很好,並且mongo會通過填充來浪費空間。

3)未來,如果它的增長過大,你可能會想縮小你的歷史收藏。通常,我們定義一個保留歷史記錄的策略(例如:5年),您可以備份和修剪比這更早的數據。如果您爲每個歷史記錄保留了單獨的文檔,則執行此操作將更容易。

我可以找到其他的原因,但我相信這3個就足夠了。