mongodb - 時間序列集合(time series collection)

1. 介紹

在mongodb 5.0 版本新增的功能,它有效地存儲了一段時期內的測量序列。時間序列數據是隨著時間收集的任何類型的數據,并由一個或多個不變參數唯一標識, 這些不變參數通常又稱為是數據源的元數據
示例:

示例 時間序列數據 元數據
天氣 溫度 傳感器標識,地理位置
股票 股票價格 股票行情、交易所
網站訪問者 訪問數量 網站地址

與普通集合相比,將時序數據存儲在時序集合中提高了查詢效率,減少了時序數據和次級索引(secondary index)的磁盤存儲空間。

2. 操作指令

  • 創建
    db.createCollection( <name>,
     {
       timeseries: {                  // Added in MongoDB 5.0
          timeField: <string>,        // required for time series collections
          metaField: <string>,
          granularity: <string>
       },
      expireAfterSeconds: <number>,
     }
    )
    
    參數名 類型 含義
    timeseries.timeField string 必選參數。每個時間序列文檔中包含日期的字段的名稱。時間序列集合中的文檔必須具有有效的 BSON 日期作為 timeField 的值
    timeseries.metaField string 可選參數,每個時間序列文檔中包含元數據的字段的名稱。指定字段中的元數據應該是用于標記一系列唯一文檔的數據。元數據應該很少(如果有的話)改變。 指定字段的名稱不可以是 _id 或與 timeseries.timeField 相同。元數據的字段可以是任何數據類型
    timeseries.granularity string 可選參數,可選值為"second","minute","hours",默認值是"seconds"。手動設置granularity參數以通過優化時間序列集合中的數據在內部存儲的方式來提高性能。選擇與連續傳入測量之間的時間跨度最接近的granularity參數值來匹配。如果指定了 timeseries.metaField,則要考慮連續的傳入的測量值 和指定的metaField字段具有相同唯一值的時間跨度。如果測量值來自同一來源,則它們通常具有相同的唯一值。如果未指定 timeseries.metaField,請考慮插入集合中的所有測量值之間的時間跨度
    expireAfterSeconds number 可選參數 ,通過指定文檔過期的秒數來啟用時間序列集合中文檔的自動刪除
    示例:
      db.weather.insertMany( [
     {
        "metadata": { "sensorId": 5578, "type": "temperature" },
        "timestamp": ISODate("2021-05-18T00:00:00.000Z"),
        "temp": 12
     },
     {
        "metadata": { "sensorId": 5578, "type": "temperature" },
        "timestamp": ISODate("2021-05-18T04:00:00.000Z"),
        "temp": 11
     },
     {
        "metadata": { "sensorId": 5578, "type": "temperature" },
        "timestamp": ISODate("2021-05-18T08:00:00.000Z"),
        "temp": 11
     },
     {
        "metadata": { "sensorId": 5578, "type": "temperature" },
        "timestamp": ISODate("2021-05-18T12:00:00.000Z"),
        "temp": 12
     },
     {
        "metadata": { "sensorId": 5578, "type": "temperature" },
        "timestamp": ISODate("2021-05-18T16:00:00.000Z"),
        "temp": 16
     },
     {
        "metadata": { "sensorId": 5578, "type": "temperature" },
        "timestamp": ISODate("2021-05-18T20:00:00.000Z"),
        "temp": 15
     }, {
        "metadata": { "sensorId": 5578, "type": "temperature" },
        "timestamp": ISODate("2021-05-19T00:00:00.000Z"),
        "temp": 13
     },
     {
        "metadata": { "sensorId": 5578, "type": "temperature" },
        "timestamp": ISODate("2021-05-19T04:00:00.000Z"),
        "temp": 12
     },
     {
        "metadata": { "sensorId": 5578, "type": "temperature" },
        "timestamp": ISODate("2021-05-19T08:00:00.000Z"),
        "temp": 11
     },
     {
        "metadata": { "sensorId": 5578, "type": "temperature" },
        "timestamp": ISODate("2021-05-19T12:00:00.000Z"),
        "temp": 12
     },
     {
        "metadata": { "sensorId": 5578, "type": "temperature" },
        "timestamp": ISODate("2021-05-19T16:00:00.000Z"),
        "temp": 17
     },
     {
        "metadata": { "sensorId": 5578, "type": "temperature" },
        "timestamp": ISODate("2021-05-19T20:00:00.000Z"),
        "temp": 12
     }
    ] )
    
  • 查詢
    示例
    db.weather.findOne({
     "timestamp": ISODate("2021-05-18T00:00:00.000Z")
    })
    

3 特性

時間序列集合的特性類似于普通集合。您可以像往常一樣插入和查詢數據。 MongoDB 將時間序列集合視為內部集合的可寫非物化視圖,在插入時自動將時間序列數據組織成優化的存儲格式。 當您查詢時間序列集合時,您每次測量操作一個文檔。對時間序列集合的查詢利用優化的內部存儲格式并更快地返回結果。

  • 索引
    時間序列集合的實現使用內部集合來減少磁盤使用和提高查詢效率。時間序列集合自動按時間排序和索引數據。 listIndexes方法 不會顯示時間序列集合的內部索引

  • 默認壓縮算法
    時間序列集合默認的壓縮算法是zstd, 而忽略全局默認壓縮算法 (snappy)。除非在創建集合時使用 storageEngine 選項指定了不同的壓縮算法。例如,要將新天氣集合的壓縮算法更改為 snappy

    db.createCollection(
    "weather",
    {
       timeseries: {
          timeField: "timestamp"
       },
       storageEngine: {
          wiredTiger: {
             configString: "block_compressor=snappy"
          }
       }
      }
    )
    

4 限制

  • 不支持的功能
    不支持如下功能:
  1. Client-side field level encryption
  2. reIndex
  3. Change streams
  4. Database Triggers
  5. GraphQL API
  6. Atlas Search
  7. Realm Sync
  8. Data API
  9. Schema validation rules
  • 聚合操作 $out and $merge
    不能使用聚合管道 $out$merge操作, 從另一個集合輸出或合并到時間序列集合。

  • 更新和刪除
    從 MongoDB 5.0.5版本開始,可以對時間序列集合執行一些刪除和更新操作。

    1. 更新命令必須滿足以下要求:

      • 查詢可能只匹配 metaField 字段值
      • update 命令只能修改 metaField 字段值
      • 必須使用僅包含更新運算符表達式的更新文檔執行更新
      • update 命令可能不會限制要更新的文檔的數量。必須使用帶有 multi: true 或 updateMany() 方法的更新命令。
      • 他更新命令不能設置 upsert: true的更新插入操作
    2. 刪除命令必須滿足以下要求

    • 查詢可能只匹配 metaField 字段值
    • 刪除命令可能不會限制要刪除的文檔數量,使用帶有 justOne: false 或 deleteMany() 方法的刪除命令。

    要自動刪除舊數據,可以設置自動刪除 (TTL)時間。 要從集合中刪除所有文檔,可以使用 drop() 方法刪除集合。

  • 集合容量
    測量文檔的最大大小為 4 MB

  • 集合修改
    集合的類型只能在創建集合時設置。
    現有集合無法轉換為時間序列集合。 同時也無法將時間序列集合轉換為不同的集合類型。

  • timeseries 參數修改

    1. timeFieldmetaField 參數只能在創建集合時設置,不能在創建后修改
    2. 一旦設置了granularity參數,一次只能增加一個級別,從"seconds"到“minutes”或從“minutes”到“hours”。不允許進行其他更改。如果您需要將粒度從“seconds”更改為“hours”,請先將粒度增加到“minutes”,然后再增加到“hours”
  • 固定集合 (capped collection)
    不能將時間序列集合創建為固定集合

  • 二級索引(secondary index)
    可以在指定為 timeFieldmetaField 的字段上添加二級索引。如果 metaField 字段的字段值是一個文檔,還可以在該文檔內的字段上創建二級索引。
    metaField 不支持以下幾種索引類型: 2d, 2dsphere,text
    二級索引不支持以下索引屬性:TTL,unique, partial

  • 分片
    從 MongoDB 5.0.6版本開始,支持分片時間序列集合。使用分片時序集合時,不能修改分片時序集合的granularity參數。

  • 事務
    事務中不能包括時間序列集合寫操作, 但是可以包括讀操作

5. TTL(Set up Automatic Removal )

創建時間序列集合時,可以使用 expireAfterSeconds 參數設置自動刪除過期的文檔:

// 示例
db.createCollection(
  "weather24h",
  {
     timeseries: {
        timeField: "timestamp",
        metaField: "metadata",
        granularity: "hours"
     },
     expireAfterSeconds: 86400
  }
)

過期閾值是 timeField 字段值加上設定的過期秒數
例如 weather24h集合中有如下的文檔

{
   "metadata": {"sensorId": 5578, "type": "temperature"},
   "timestamp": ISODate("2021-05-18T10:00:00.000Z"),
   "temp": 12
}

那該文檔將在ISODate("2021-05-18T10:00:00.000Z") + 86400s 的時間過期

  • 過期文檔刪除時機
    MongoDB 不保證過期數據會在過期后立即被刪除。一旦存儲桶中的所有文檔都過期,刪除過期存儲桶的后臺任務會在下次運行期間刪除該存儲桶。單個桶允許覆蓋的最大時間跨度由時間序列集合的 granularity參數決定:

    刪除過期存儲桶的后臺任務每 60 秒運行一次。因此,在文檔過期、桶中所有其他文檔過期和后臺任務運行期間,文檔可能會保留在集合中。 由于刪除操作的持續時間取決于 mongod 實例的工作負載,因此在后臺任務運行之間的 60 秒時間間隔之后,過期數據可能會存在一段時間。
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,363評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,497評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,305評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,962評論 1 311
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,727評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,193評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,257評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,411評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,945評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,777評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,978評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,519評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,216評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,657評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,960評論 2 373

推薦閱讀更多精彩內容