[MongoDB] 使用aggregate計算四分位數

  • 476
  • 0

在MongoDB中使用聚合(aggregate)計算四分位數(Quartile)

引用自維基百科

四分位數(Quartile)是統計學中分位數的一種,即把所有數值由小到大排列並分成四等份,處於三個分割點位置的數值就是四分位數。

假設有一個 numbers collection如下:

[
  {
    "values": [1, 2, 3, 4]
  },
  {
    "values": [7, 15, 36, 39, 40, 41]
  },
  {
    "values": [6, 7, 15, 36, 39, 40, 41, 42, 43, 47, 49]
  }
]

 

以下是使用聚合(aggregate)計算四分位數:

db.getCollection("numbers").aggregate(
	[
		{
			$addFields: {
			    count: { $size: '$values' }
			}
		},
		{
			$addFields: {
			    q1_1: { $floor: { $subtract: [ { $multiply: ['$count', 0.25] }, 0.25] } },
			    q1_2: { $floor: { $multiply: ['$count', 0.25] } },
			    q2_1: { $floor: { $subtract: [ { $multiply: ['$count', 0.5] }, 0.5] } },
			    q2_2: { $floor: { $multiply: ['$count', 0.5] } },
			    q3_1: { $floor: { $subtract: [ { $multiply: ['$count', 0.75] }, 0.25] } },
			    q3_2: { $floor: { $multiply: ['$count', 0.75] } },
			    min: { $arrayElemAt: ['$values', 0] },
			    max: { $arrayElemAt: ['$values', { $subtract: ['$count', 1] } ] }
			}
		},
		{
			$addFields: {
			    q1: { $avg: [ { $arrayElemAt: ['$values', '$q1_1'] }, { $arrayElemAt: ['$values', '$q1_2'] } ] },
			    q2: { $avg: [ { $arrayElemAt: ['$values', '$q2_1'] }, { $arrayElemAt: ['$values', '$q2_2'] } ] },
			    q3: { $avg: [ { $arrayElemAt: ['$values', '$q3_1'] }, { $arrayElemAt: ['$values', '$q3_2'] } ] }
			}
		},
		{
			$project: {
			    q1_1: false,
			    q1_2: false,
			    q2_1: false,
			    q2_2: false,
			    q3_1: false,
			    q3_2: false
			}
		}
	]
);

 

執行結果:

 

程式碼說明:

  1. 用 $addFields 計算陣列長度,並存到 count 欄位
  2. 用 $addFields 計算Q1、Q2、Q3的兩個index以及最小值(min)與最大值(max)
  3. 用 $addFields 計算最終的Q1、Q2、Q3
  4. 用 $project 去除不需要用到的欄位
  5. 如果 count  大於0,則可以算出四分位數,如果等於0,則四分位數會是null。可以在最前面加一個stage用 $match 過濾掉陣列長度為0的資料,以免出現null的情況。

 

 

文章內容僅提供技術分享,如有錯誤還請不吝指教。