文档菜单
文档首页
/
MongoDB 手册
/ / /

中位数(聚合)

本页

  • 定义
  • 语法
  • 命令字段
  • 行为
  • 示例
  • 了解更多
$median

新增于版本7.0.

返回近似的中位数,即第50个百分位数,作为一个标量值。中位数,第50个百分位数,作为标量值。

您可以在 累加器 阶段或作为 聚合表达式 使用 $median

$median 的语法是

{
$median: {
input: <number>,
method: <string>
}
}

$median 以下字段

字段
类型
必需性
描述
input
表达式
必需
$median 计算数据的第50个百分位数。 input 必须是字段名或评估为数值类型的表达式。如果表达式不能转换为数值类型,则 $median 计算会忽略它。
method
字符串
必需
mongod计算第50百分位数的方法。该方法必须是'approximate'

您可以在

  • $group阶段将其用作累加器

  • $setWindowFields阶段将其用作累加器

  • $project阶段将其用作聚合表达式

$median作为累加器具有以下特性:

  • 为阶段中的所有文档计算单个结果。

  • 使用t-digest算法计算近似百分位数指标。

  • 使用近似方法扩展到大量数据。

$median作为聚合表达式具有以下特性:

  • 接受数组作为输入

  • 为每个输入文档计算单独的结果

$group阶段,$median是一个累加器,为窗口中的所有文档计算一个值。

$project阶段,$median是一个聚合表达式,为每个文档计算值。

$setWindowFields阶段,$median返回一个类似于聚合表达式的每个文档的结果,但结果是在文档组上计算的,类似于累加器。

$group阶段,$median始终使用近似计算方法。

$project阶段,即使指定了近似方法,$median也可能使用离散计算方法。

$setWindowFields阶段,工作负载决定了$median使用的计算方法。

$median返回的计算百分位数可能有所不同,即使在同一数据集中也是如此。这是因为算法计算的是近似值。

重复样本可能导致歧义。如果有大量重复的样本,百分位数可能无法代表实际的样本分布。考虑一个所有样本都相同的数据集。数据集中的所有值都位于或低于任何百分位数。实际上,“50百分位数”值将代表0或100个样本。

如果您在$project阶段将$median用作聚合表达式,则可以使用数组作为输入。$median忽略非数值数组值。

语法是

{
$median:
{
input: [ <expression1, <expression2>, ..., <expressionN> ],
method: <string>
}
}

窗口函数允许您在相邻文档的“窗口”上计算结果。当每个文档通过管道时,$setWindowFields 阶段

  • 重新计算当前窗口中的文档集合

  • 为集合中的所有文档计算一个值

  • 为该文档返回一个单一值

您可以在 $setWindowFields 阶段中使用 $median 来计算时间序列或其他相关数据的滚动统计。

当您在 $setWindowField 阶段中使用 $median 时,input 值必须是字段名称。如果您输入的是一个数组而不是字段名称,则操作会失败。

以下示例使用 testScores 集合。创建该集合

db.testScores.insertMany( [
{ studentId: "2345", test01: 62, test02: 81, test03: 80 },
{ studentId: "2356", test01: 60, test02: 83, test03: 79 },
{ studentId: "2358", test01: 67, test02: 82, test03: 78 },
{ studentId: "2367", test01: 64, test02: 72, test03: 77 },
{ studentId: "2369", test01: 60, test02: 53, test03: 72 }
] )

创建一个计算中值值的累加器

db.testScores.aggregate( [
{
$group: {
_id: null,
test01_median: {
$median: {
input: "$test01",
method: 'approximate'
}
}
}
}
] )

输出

{ _id: null, test01_median: 62 }

_id 字段值为 null 因此 $group 选择集合中的所有文档。

$median 累加器从 test01 字段获取输入。在此示例中,$median 计算了该字段的median值,即 62

$group 阶段,$median 是一个累加器,为所有文档计算一个单一值。在 $project 阶段,$median 是一个聚合表达式,为每个文档计算值。

您可以在 $project 阶段使用字段名或数组作为输入。

db.testScores.aggregate( [
{
$project: {
_id: 0,
studentId: 1,
testMedians: {
$median: {
input: [ "$test01", "$test02", "$test03" ],
method: 'approximate'
}
}
}
}
] )

输出

{ studentId: '2345', testMedians: 80 },
{ studentId: '2356', testMedians: 79 },
{ studentId: '2358', testMedians: 78 },
{ studentId: '2367', testMedians: 72 },
{ studentId: '2369', testMedians: 60 }

$median 是聚合表达式时,每个 studentId 都有一个结果。

要基于本地数据趋势建立您的百分位数值,请在 $setWindowField 聚合管道阶段使用 $median

本示例创建了一个用于过滤分数的窗口

db.testScores.aggregate( [
{
$setWindowFields: {
sortBy: { test01: 1 },
output: {
test01_median: {
$median: {
input: "$test01",
method: 'approximate'
},
window: {
range: [ -3, 3 ]
}
}
}
}
},
{
$project: {
_id: 0,
studentId: 1,
test01_median: 1
}
}
] )

输出

{ studentId: '2356', test01_median: 60 },
{ studentId: '2369', test01_median: 60 },
{ studentId: '2345', test01_median: 60 },
{ studentId: '2367', test01_median: 64 },
{ studentId: '2358', test01_median: 64 }

在本示例中,每个文档的中值计算还结合了它之前和之后三份文档的数据。

$percentile 操作符》是 $median 操作符的更通用版本,允许您设置一个或多个百分位数。

有关窗口函数的更多信息,请参阅: $setWindowFields

返回

最大N-数组元素