欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MongoDB時間戳轉日期及日期分組實例代碼

 更新時間:2023年05月16日 10:30:06   作者:耳冉鵝  
時間戳(timestamp)通常是一個字符序列,唯一地標識某一刻的時間,下面這篇文章主要給大家介紹了關于MongoDB時間戳轉日期及日期分組的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下

前言

最近遇到的一個數(shù)據(jù)統(tǒng)計折線圖的性能優(yōu)化點,可以說是一定思維上的轉變,就記錄下咯

背景:cron定時任務讀取當前統(tǒng)計數(shù)據(jù)的異常值,頻率為每五分鐘記錄一次,折線圖要求獲取每日的異常項峰值

最一開始的想法:將數(shù)據(jù)讀取到內存中進行條件過濾、計算

首先根據(jù)時間戳將數(shù)據(jù)以日期作為分組,其次在每個分組中獲取異常項的峰值數(shù)據(jù),時間復雜度O(n*n),最好以日期分組列表+峰值數(shù)據(jù)列表作為對象返回結果

遇到性能問題:一天的數(shù)據(jù)量為(60/5)*24=288,默認日期為15天,則統(tǒng)計的數(shù)據(jù)量為4230,接口返回甚至需要8、9秒的時間,作為一個項目的門面折線圖,這種情況 達咩!

優(yōu)化的念頭:我要拿每天的峰值數(shù)據(jù),怎么才能直接取到每天的峰值呢,mongo的聚合是不是可以做到??? $group可以按日期做分組, $max可以拿到最大值,接下來一個 $sort好像是就成了吧! 說干就干??!

接下來的聚合語句均為mongo pipeline,最后附上golang的bson條件哈

// ResultCountModel _
type ResultCountModel struct {
	CommonBase `json:",inline" yaml:",inline" bson:",inline"`
	ErrorCount int   `json:"error_count" bson:"error_count"`
	Timestamp  int64 `json:"timestamp" bson:"timestamp"`
	MaxTime    int64 `json:"max_time" bson:"max_time"`
}

數(shù)據(jù)結構定義如上,這里使用CommonBase,是因為在$group聚合后會得到_id唯一標識字段,因此便于獲取最后的聚合結果,在定義結構體時將其加上;timestamp單位為毫秒

1、日期篩選

第一步,毫無疑問,對時間戳timestamp進行日期的過濾

  {
    $match: {
        timestamp: {
            $gte: 1671897600000, // min_timestamp
            $lt: 1673280000000   // max_timestamp
        }
    }
  }
  • $gte 大于等于
  • $lt 小于

2、日期轉換

第二步,根據(jù)時間戳大小進行日期的轉換,這里是用的是$project, 將具有請求字段的文檔傳遞到管道中的下一階段。指定的字段可以是輸入文檔中的現(xiàn)有字段或是新計算的字段

使用$project主要思路是,將timestamp時間戳轉換為標準日期,之后輸出為想要的format形式;同時使用 $project保留需要的字段

時間戳轉換日期

核心方法:$dateToString

{ 
  $dateToString: {
    date: <dateExpression>,
    format: <formatString>,
    timezone: <tzExpression>,
    onNull: <expression>
  }
}
  • date :要轉換的字符串日期,必須是解析為Date、Timestamp、ObjectID 的有效表達式
  • format: 日期格式規(guī)范
  • timezone:運算結果的時區(qū),常用UTC偏移量
  • onNull: date為null或缺失時要返回的值

日期格式想要“月份-日期”,那format: “%m-%d”

日期數(shù)據(jù)這里,如果直接使用輸入文檔中的現(xiàn)有字段的話 date: “$timestamp”,則會報錯:PlanExecutor error during aggregation :: caused by :: can’t convert from BSON type long to Date

因此我們需要將時間戳轉換為日期: 即格林威治開始時間(1970-01-01 00:00:00)+時間戳+時差

  date:{
    $add:[
      new Date(0),
      "$timestamp",
      28800000
    ]
  },

注意??:

  • MongoDB時間的基本單位為毫秒,所以本文直接使用”$timestamp”即可;若時間單位為秒級時,則需要使用 $multiply進行乘法運算:{ $multiply:[" $timestamp”,1000]}
  • MongoDB是UTC時區(qū),即中時區(qū)(0度經線), 中國為東八區(qū),因此需要使用timezone添加8小時(即28800000毫秒)

pipeline如下:

  day:{
    $dateToString:{
      format:"%m-%d",
      date:{
        $add:[
          new Date(0),
          "$timestamp",
          28800000
        ]
      },
    }
  },

保留需要字段

/**
 * specifications: The fields to
 *   include or exclude.
 */
{
  timestamp:1,
  error_count:1,
}

$project將保留字段置為1即可進行數(shù)據(jù)保留操作

第二步完整pipeline如下:

{
    $project: {
        day: {
            $dateToString: {
                format: '%m-%d',
                date: {
                    $add: [
                        ISODate('1970-01-01T00:00:00.000Z'),
                        '$timestamp',
                        28800000
                    ]
                }
            }
        },
        timestamp: 1,
        error_count: 1
    }
},

3、日期分組

第三步,使用$group進行日期分組

{
  $group:
    {
      _id: <expression>, // Group key
      <field1>: { <accumulator1> : <expression1> },
      ...
    }
 }
  • _id: 表達式指定組密鑰
  • field: 計算使用的累加器運算符

這里我們需要將第二步獲得的日期轉換進行分組聚合,同時獲取每個分組的異常項最大值即峰值數(shù)據(jù)

{
    $group: {
        _id: '$day',
        error_count: {
            $max: '$error_count'
        },
        max_time: {
            $max: '$timestamp'
        }
    }
}, 

這里額外獲取了max_time字段,主要用于在計算統(tǒng)計數(shù)據(jù)時的排序,在最后排序部分會使用到

4、日期排序

這里做一個假設,如果不使用max_time的話,如何將數(shù)據(jù)進行按日期的排序呢? 如果根據(jù)_id進行排序,則會出現(xiàn)“上年末”排序在“下年初”的情況(感謝現(xiàn)在的??,不然會忘記這個問題)

所以將每個分組的最大時間戳保留下來時很有必要的!

這里取$max $min都是可以的哈

{
    $sort: {
        max_time: 1
    }
}

最終完整pipeline:

[{
 $match: {
  timestamp: {
   $gte: 1671897600000,
   $lt: 1673280000000
  }
 }
}, {
 $project: {
  day: {
   $dateToString: {
    format: '%m-%d',
    date: {
     $add: [
      ISODate('1970-01-01T00:00:00.000Z'),
      '$timestamp',
      28800000
     ]
    }
   }
  },
  timestamp: 1,
  error_count: 1
 }
}, {
 $group: {
  _id: '$day',
  error_count: {
   $max: '$error_count'
  },
  max_time: {
   $max: '$timestamp'
  }
 }
}, {
 $sort: {
  max_time: 1
 }
}]
[{
 $match: {
  timestamp: {
   $gte: 1671897600000,
   $lt: 1673280000000
  }
 }
}, {
 $project: {
  day: {
   $dateToString: {
    format: '%m-%d',
    date: {
     $add: [
      ISODate('1970-01-01T00:00:00.000Z'),
      '$timestamp',
      28800000
     ]
    }
   }
  },
  timestamp: 1,
  error_count: 1
 }
}, {
 $group: {
  _id: '$day',
  error_count: {
   $max: '$error_count'
  },
  max_time: {
   $max: '$timestamp'
  }
 }
}, {
 $sort: {
  max_time: 1
 }
}]

在golang里面,Aggregate則直接使用pipeline即可,亦可轉換為filter使用

filter代碼:

filter := bson.A{
		bson.D{{"$match", bson.D{
			{"timestamp", bson.D{
				{"$gte", param.MinTimestamp},
				{"$lt", param.MaxTimestamp},
			}}}},
		},
		bson.D{{"$project", bson.D{
			{"day", bson.D{
				{"$dateToString", bson.D{
					{"format", "%m-%d"},
					{"date", bson.D{
						{"$add", bson.A{
							time.Date(1970, 1, 1, 0, 0, 0, 0, time.UTC),
							"$timestamp",
							28800000,
						}},
					}},
				}},
			}},
			{"error_count", 1},
			{"timestamp", 1},
		}}},
		bson.D{{"$group", bson.D{
			{"_id", "$day"},
			{"max_time", bson.D{{"$max", "$timestamp"}}},
			{"error_count", bson.D{{"$max", "$error_count"}}},
		}}},
		bson.D{{"$sort", bson.D{{"max_time", 1}}}},
	}

完結撒花??

補充:解決MongoDB存儲時間時差的問題

MongoDB存儲時間類型數(shù)據(jù)時,都是先轉換為UTC時間,然后存儲到數(shù)據(jù)庫中,當我們取出存儲的時間時,就會出現(xiàn)時差的問題。比如我們用的北京時間,讀取到的數(shù)值就會看到比當前時間少了8個小時,難道說我們在每次讀取的時候都要單獨處理一下時間嗎,這就比較麻煩。其實,我們可以在存儲的時候進行相應的處理,只需使用getTimezoneOffset()和toISOString()函數(shù)。

getTimezoneOffset函數(shù):返回此地區(qū)的時差(當?shù)貢r間與GMT格林威治標準時間的地區(qū)時差),單位為分鐘。

<script>
  // 我們是東八區(qū)
  var d = new Date();
  var tz = d.getTimezoneOffset();
  console.log(tz);  // -480
</script>

toISOString()函數(shù):使用ISO標準將 Date 對象轉換為字符串。

該標準稱為 ISO-8601 ,格式為: YYYY-MM-DDTHH:mm:ss.sssZ。

封裝時間轉換函數(shù)

localDate(v) {
    const d = new Date(v || Date.now());
    d.setMinutes(d.getMinutes() - d.getTimezoneOffset());
    return d.toISOString();
},

我們在存儲時間的時候調用localDate()這個函數(shù)就可以了,無論你處在哪個時區(qū)結果顯示都和當?shù)貢r間一樣。

總結

到此這篇關于MongoDB時間戳轉日期及日期分組的文章就介紹到這了,更多相關MongoDB時間戳轉日期內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • MongoDB使用mongoexport和mongoimport命令,批量導出和導入JSON數(shù)據(jù)到同一張表的實例

    MongoDB使用mongoexport和mongoimport命令,批量導出和導入JSON數(shù)據(jù)到同一張表的實例

    今天小編就為大家分享一篇關于MongoDB使用mongoexport和mongoimport命令,批量導出和導入JSON數(shù)據(jù)到同一張表的實例,小編覺得內容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-10-10
  • Windows系統(tǒng)下安裝MongoDB并內網(wǎng)穿透遠程連接

    Windows系統(tǒng)下安裝MongoDB并內網(wǎng)穿透遠程連接

    這篇文章主要給大家介紹了關于Windows系統(tǒng)下安裝MongoDB并內網(wǎng)穿透遠程連接的相關資料,文中通過圖文將步驟介紹的非常詳細,對大家學習或者使用MongoDB具有一定的參考學習價值,需要的朋友可以參考下
    2023-03-03
  • Centos 7下Mongodb開機無法自啟動的解決方法

    Centos 7下Mongodb開機無法自啟動的解決方法

    這篇文章主要介紹了Centos 7下Mongodb開機無法自啟動的解決方法,文中介紹的非常詳細,對大家具有一定的參考價值,需要的朋友們下面來一起看看吧。
    2017-03-03
  • 基于Mongodb分布式鎖解決定時任務并發(fā)執(zhí)行問題

    基于Mongodb分布式鎖解決定時任務并發(fā)執(zhí)行問題

    這篇文章主要介紹了基于Mongodb分布式鎖解決定時任務并發(fā)執(zhí)行問題,網(wǎng)上有很多分布式鎖的實現(xiàn)方案,基于redis、zk、等有很多,但是我的就是一個用了mysql和mongo的小應用,本文給大家詳細講解,需要的朋友可以參考下
    2023-04-04
  • Pycharm連接MongoDB數(shù)據(jù)庫安裝教程詳解

    Pycharm連接MongoDB數(shù)據(jù)庫安裝教程詳解

    這篇文章主要介紹了Pycharm連接MongoDB數(shù)據(jù)庫安裝教程,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • MongoDB教程之查詢操作實例

    MongoDB教程之查詢操作實例

    這篇文章主要介紹了MongoDB教程之查詢操作實例,本文講解了基本查詢、查詢條件、null數(shù)據(jù)類型的查詢、正則查詢、數(shù)組數(shù)據(jù)查詢、內嵌文檔查詢等數(shù)據(jù)查詢技巧,需要的朋友可以參考下
    2015-05-05
  • MongoDB分組查詢和聚合查詢實例教程

    MongoDB分組查詢和聚合查詢實例教程

    聚合(aggregate)是MongoDB的高級查詢語言,它允許我們通過轉化合并多個文檔的數(shù)據(jù)來生成新的在單個文檔里不存在的文檔信息,下面這篇文章主要給大家介紹了關于MongoDB分組查詢和聚合查詢的相關資料,需要的朋友可以參考下
    2023-05-05
  • MongoDB快速翻頁的方法

    MongoDB快速翻頁的方法

    這篇文章主要為大家詳細介紹了MongoDB快速翻頁的方法,通過實例學習在MongoDB中翻閱數(shù)據(jù)的不同方式,感興趣的小伙伴們可以參考一下
    2016-05-05
  • 在阿里云centos下部署mongodb教程

    在阿里云centos下部署mongodb教程

    這里給大家分享的是作者在阿里云centos下部署mongodb的過程全記錄,非常的詳細,也遇到了很多問題,最終部署成功,希望對大家能夠有所幫助
    2017-08-08
  • MongoDB查詢性能優(yōu)化驗證及驗證

    MongoDB查詢性能優(yōu)化驗證及驗證

    這篇文章主要介紹了MongoDB查詢性能驗證及優(yōu)化的相關知識,涉及到MongoDB 查詢優(yōu)化原則知識點,本文介紹的非常詳細,具有參考借鑒價值,感興趣的朋友一起學習吧
    2016-02-02

最新評論