MongoDB聚合运算符:$stdDevPop

MongoDB聚合运算符:$stdDevPop

文章目录

$stdDevPop聚合运算符用来计算输入值的总体标准差。如果确认数据代表了整个数据集,且不希望对更大的群体进行归纳,可以使用 $stdDevPop来计算总体标准差。如果数据仅代表了总体的一部分样本,但又想把结论推广到整个数据集,则应该使用 $stdDevSamp

$stdDevPop可以应用于下面的阶段:

  • $addFields,从MongoDB3.4开始支持
  • $group
  • $match阶段的$expr表达式
  • $project
  • $replaceRoot,从MongoDB 3.4开始支持
  • $replaceWith,从MongoDB 4.2开始支持
  • $set,从MongoDB 4.2开始支持
  • $setWindowFields,从MongoDB 5.0开始支持

语法

当用于$bucket$bucketAuto$group$setWindowFields阶段时的语法为:

js 复制代码
{ $stdDevPop: <expression> }

当用于其它阶段时,$stdDevPop的语法有两种形式:

  • 操作数为一个表达式:

    js 复制代码
    { $stdDevPop: <expression> }
  • 操作数为一个表达式列表:

    js 复制代码
     { $stdDevPop: [ <expression1>, <expression2> ... ]  }

<expression>为可解析为数组的表达式。

参数可以是任何能够解析为数组的表达式。

使用

非数值类型的值

$stdDevPop忽略所有非数值的值,如果所有的操作数都是非数值的值,$stdDevPop返回null。

单个值

如果样本只有一个数值类型的值,$stdDevPop返回0。

数组操作数

$group$setWindowFields阶段,如果表达式解析为数组,$stdDevPop会将操作数视为非数字值,对计算没有影响。

针对其它阶段:

  • 当使用单个表达式作为操作数时,如果表达式解析为数组,$stdDevPop会遍历数组元素,并对数字元素进行操作返回单个值。
  • 当使用表达式列表作为操作数,如果表达式解析为数组,$stdDevPop不会遍历该数组,而是将数组视为非数字值。

窗口值

对于$setWindowFields阶段窗口的值:

  • 忽略窗口中的非数值、空值和缺失字段。
  • 如果窗口为空,则返回 null。
  • 如果窗口中包含 NaN 值,则返回空值。
  • 如果窗口包含 Infinity 值,则返回空值。
  • 如果前面几点都不适用,则返回一个 double 值。

举例

应用于$group阶段

使用下面的脚本创建users集合:

js 复制代码
db.users.insertMany( [
   { _id : 1, name : "dave123", quiz : 1, score : 85 },
   { _id : 2, name : "dave2", quiz : 1, score : 90 },
   { _id : 3, name : "ahn", quiz : 1, score : 71 },
   { _id : 4, name : "li", quiz : 2, score : 96 },
   { _id : 5, name : "annT", quiz : 2, score : 77 },
   { _id : 6, name : "ty", quiz : 2, score : 82 }
] )

下面的例子计算测验的标准差:

js 复制代码
db.users.aggregate( [
   { $group: { _id: "$quiz", stdDev: { $stdDevPop: "$score" } } }
] )

操作结果如下:

json 复制代码
{ "_id" : 2, "stdDev" : 8.04155872120988 }
{ "_id" : 1, "stdDev" : 8.04155872120988 }

$project阶段使用

使用下面的脚本创建quizzes集合:

js 复制代码
db.quizzes.insertMany( [
   {
      _id : 1,
      scores : [
         { name : "dave123", score : 85 },
         { name : "dave2", score : 90 },
         { name : "ahn", score : 71 }
      ]
   },
   {
      _id : 2,
      scores : [
         { name : "li", quiz : 2, score : 96 },
         { name : "annT", score : 77 },
         { name : "ty", score : 82 }
      ]
   }
] )

下面的示例计算了每次测验的标准差:

js 复制代码
db.quizzes.aggregate( [
   { $project: { stdDev: { $stdDevPop: "$scores.score" } } }
] )

操作结果如下:

json 复制代码
{ "_id" : 2, "stdDev" : 8.04155872120988 }
{ "_id" : 1, "stdDev" : 8.04155872120988 }

$setWindowFields阶段使用

使用下面的脚本创建cakeSales集合,包含了在加利福尼亚州(CA)和华盛顿州(WA)的蛋糕销售记录:

js 复制代码
db.cakeSales.insertMany( [
   { _id: 0, type: "chocolate", orderDate: new Date("2020-05-18T14:10:30Z"),
     state: "CA", price: 13, quantity: 120 },
   { _id: 1, type: "chocolate", orderDate: new Date("2021-03-20T11:30:05Z"),
     state: "WA", price: 14, quantity: 140 },
   { _id: 2, type: "vanilla", orderDate: new Date("2021-01-11T06:31:15Z"),
     state: "CA", price: 12, quantity: 145 },
   { _id: 3, type: "vanilla", orderDate: new Date("2020-02-08T13:13:23Z"),
     state: "WA", price: 13, quantity: 104 },
   { _id: 4, type: "strawberry", orderDate: new Date("2019-05-18T16:09:01Z"),
     state: "CA", price: 41, quantity: 162 },
   { _id: 5, type: "strawberry", orderDate: new Date("2019-01-08T06:12:03Z"),
     state: "WA", price: 43, quantity: 134 }
] )

下面的示例在 $setWindowFields 阶段使用 $stdDevPop 输出每个州蛋糕销售数量的人口标准差:

js 复制代码
db.cakeSales.aggregate( [
   {
      $setWindowFields: {
         partitionBy: "$state",
         sortBy: { orderDate: 1 },
         output: {
            stdDevPopQuantityForState: {
               $stdDevPop: "$quantity",
               window: {
                  documents: [ "unbounded", "current" ]
               }
            }
         }
      }
   }
] )

在本例中:

  • partitionBy: "$state"按照州state对集合的文档进行分区,有CAWA两个区。
  • sortBy: { orderDate: 1 }根据orderDate对分区内文档进行由小到大的排序,orderDate最早的排在第一个。
  • output使用$stdDevPop将窗口内文档的quantity标准差赋予stdDevPopQuantityForState字段。窗口包含无界下限和输出中的当前文档之间的文档,这意味着$stdDevPop返回分区开头和当前文档之间文档的数量总体标准差。

在此示例输出中,CAWAquantity总体标准差放在stdDevPopQuantityForState字段:

操作结果如下:

js 复制代码
{ _id : 4, type : "strawberry", orderDate : ISODate("2019-05-18T16:09:01Z"),
  state : "CA", price : 41, quantity : 162, stdDevPopQuantityForState : 0 }
{ _id : 0, type : "chocolate", orderDate : ISODate("2020-05-18T14:10:30Z"),
  state : "CA", price : 13, quantity : 120, stdDevPopQuantityForState : 21 }
{ _id : 2, type : "vanilla", orderDate : ISODate("2021-01-11T06:31:15Z"),
  state : "CA", price : 12, quantity : 145, stdDevPopQuantityForState : 17.249798710580816 }
{ _id : 5, type : "strawberry", orderDate : ISODate("2019-01-08T06:12:03Z"),
  state : "WA", price : 43, quantity : 134, stdDevPopQuantityForState : 0 }
{ _id : 3, type : "vanilla", orderDate : ISODate("2020-02-08T13:13:23Z"),
  state : "WA", price : 13, quantity : 104, stdDevPopQuantityForState : 15 }
{ _id : 1, type : "chocolate", orderDate : ISODate("2021-03-20T11:30:05Z"),
  state : "WA", price : 14, quantity : 140, stdDevPopQuantityForState : 15.748015748023622 }
相关推荐
超级小忍8 分钟前
如何配置 MySQL 允许远程连接
数据库·mysql·adb
吹牛不交税20 分钟前
sqlsugar WhereIF条件的大于等于和等于查出来的坑
数据库·mysql
hshpy43 分钟前
setting up Activiti BPMN Workflow Engine with Spring Boot
数据库·spring boot·后端
月初,1 小时前
MongoDB学习和应用(高效的非关系型数据库)
学习·mongodb·nosql
文牧之2 小时前
Oracle 审计参数:AUDIT_TRAIL 和 AUDIT_SYS_OPERATIONS
运维·数据库·oracle
篱笆院的狗2 小时前
如何使用 Redis 快速实现布隆过滤器?
数据库·redis·缓存
洛神灬殇3 小时前
【LLM大模型技术专题】「入门到精通系列教程」基于ai-openai-spring-boot-starter集成开发实战指南
网络·数据库·微服务·云原生·架构
小鸡脚来咯3 小时前
redis分片集群架构
数据库·redis·架构
christine-rr4 小时前
征文投稿:如何写一份实用的技术文档?——以软件配置为例
运维·前端·网络·数据库·软件构建
海尔辛4 小时前
SQL 基础入门
数据库·sql