MongoDB权威指南之聚合框架

前言

许多应用程序需要进行某一类的数据分析。MongoDB 为使用聚合框架原生地进行分析提供了强大的支持。本章介绍这个框架和它提供的一些基本工具。

聚合框架基于管道的概念。使用聚合管道可以从MongoDB 集合获取输入,并将该集合中的文档传递到一个或多个阶段,每个阶段对其输入执行不同的操作。

在聚合管道中,一个阶段就是一个数据处理单元。它一次接收一个输入文档流,一次处理一个文档,并且一次产生一个输出文档流。

阶段入门:常见操作

使用**$match**进行过滤

JavaScript 复制代码
db.companies.aggregate([
    {$match: {founded_year: 2004}},
])

这相当于使用了 find API

JavaScript 复制代码
db.companies.find({founded_year: 2004})

使用**$project**添加一个投射阶段来将每个文档的输出减少到几个字段。

JavaScript 复制代码
db.companies.aggregate([
  {$match: {founded_year: 2004}},
  {$project: {
    _id: 0,
    name: 1,
    founded_year: 1
  }}
])

使用**$limit**把结果集限制为5。

JavaScript 复制代码
db.companies.aggregate([
  {$match: {founded_year: 2004}},
  {$limit: 5},
  {$project: {
    _id: 0,
    name: 1}}
])

无论 MongoDB 查询规划器在给定版本中进行何种类型的优化,都应该始终注意聚合管道的效率。确保在构建管道时限制从一个阶段传递到另一个阶段的文档数量。

使用$sort对文档进行升序排序

JavaScript 复制代码
db.companies.aggregate([
    { $match: { founded_year: 2004 } },
    { $sort: { name: 1} },
    { $limit: 5 },
    { $project: {
        _id: 0,
        name: 1 } }
])

使用**$skip**跳过10个文档。

JavaScript 复制代码
db.companies.aggregate([
  {$match: {founded_year: 2004}},
  {$sort: {name: 1}},
  {$skip: 10},
  {$limit: 5},
  {$project: {
    _id: 0,
    name: 1}},
])

表达式

  • 布尔表达式允许使用 AND、OR 和 NOT。
  • 集合表达式允许将数组作为集合来处理。特别地,可以取两个或多个集合的交集或并集,也可以取两个集合的差值并执行一些其他的集合运算。
  • 比较表达式能够表达许多不同类型的范围过滤器。
  • 算术表达式能够计算上限(ceiling)、下限(floor)、自然对数和对数,以及执行简单的算术运算
  • 数组表达式为操作数组提供了强大的功能,包括过滤数组元素、对数组进行分割或从特定数组中获取某一个范围的值。
  • 变量表达式允许处理文字、解析日期值及条件表达式。
  • 累加器提供了计算总和、描述性统计和许多其他类型值的能力。

$project

在投射阶段中,用于指定 ipo、valuation 和 funders 值的 $字符表示这些值应被解释为字段路径,并分别用于为每个字段选择应投射的值。

JavaScript 复制代码
db.companies.aggregate([
  {$match: {"funding_rounds.investments.financial_org.permalink": "greylock" }},
  {$project: {
    _id: 0,
    name: 1,
    ipo: "$ipo.pub_year",
    valuation: "$ipo.valuation_amount",
    funders: "$funding_rounds.investments.financial_org.permalink"
  }}
]).pretty()

$unwind

$unwind 会从输入文档中获取一个数组,并为该数组中的每个元素创建一个输出文档

![[Pasted image 20231109174515.png]]

累加器

聚合框架提供的累加器可以执行对特定字段中的所有值进行求和($sum)、计算平均值($avg)等操作。$first$last 也被视为累加器,因为在它们所在的阶段中所有经过的文档的值都会被检查。$max$min 是另外两个累加器的例子,它们会查看文档流并只保存看到的其中一个值。可以使用$mergeObjects 将多个文档合并为单个文档。

还有用于数组的累加器。当文档通过管道传递时,可以将值$push 到数组中。$addToSet$push 非常相似,只是它可以确保结果数组中不包含重复的值。

分组简介

分组阶段执行的功能类似于 SQL 中的 GROUP BY 命令。

在分组阶段,可以将多个文档的值聚合在一起并对它们执行某种类型的聚合操作,比如计算平均值。

分组阶段中的_id字段

在分组阶段使用具有多个字段的文档作为 _id 值是完全没问题的。

JavaScript 复制代码
db.companies.aggregate([
  { $match: { founded_year: { $gte: 2013 } } },
  { $group: {
    _id: { founded_year: "$founded_year"},
    companies: { $push: "$name" }
  } },
  { $sort: { "_id.founded_year": 1 } }
]).pretty()

管道输出值如下:

JavaScript 复制代码
{
  "_id" : {
    "founded_year" : 2013
  },
  "companies" : [
    "Fixya",
    "Wamba",
    "Advaliant",
    "Fluc",
    "iBazar",
    "Gimigo",
    "SEOGroup",
    "Clowdy",
    "WhosCall",
    "Pikk",
    "Tongxue",
    "Shopseen",
    "VistaGen Therapeutics"
  ]
}

将聚合管道结果写入集合中

作为两个特定的阶段, <math xmlns="http://www.w3.org/1998/Math/MathML"> o u t 和 out 和 </math>out和merge 可以将聚合管道生成的文档写入集合中。这两个阶段不能同时使用,并且任一阶段必须是聚合管道的最后一个阶段

  • $merge 是在 MongoDB 4.2 中引入的,如果可以使用的话,它是将结果写入集合中的首选方式。
  • $out 有一些限制:它只能写入相同的数据库;如果集合已经存在,那么它会覆盖任何现有的集合;它不能写入已分片的集合中。
  • <math xmlns="http://www.w3.org/1998/Math/MathML"> m e r g e 可以写入任何数据库和集合中,无论是否分片。 merge 可以写入任何数据库和集合中,无论是否分片。 </math>merge可以写入任何数据库和集合中,无论是否分片。merge 还可以在处理现有集合时对结果进行合并(插入新文档、与现有文档合并、操作失败、保留现有文档或使用自定义更新处理所有文档)。但使用 $merge 的真正优势在于,它可以创建按需生成的物化视图(materialized view),在管道运行的过程中,输出到集合的内容会进行增量更新。
相关推荐
王哈哈^_^1 小时前
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
前端·人工智能·深度学习·yolo·目标检测·计算机视觉·pyqt
cs_dn_Jie2 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic2 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿2 小时前
webWorker基本用法
前端·javascript·vue.js
cy玩具3 小时前
点击评论详情,跳到评论页面,携带对象参数写法:
前端
qq_390161773 小时前
防抖函数--应用场景及示例
前端·javascript
John.liu_Test4 小时前
js下载excel示例demo
前端·javascript·excel
Yaml44 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
PleaSure乐事4 小时前
【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案
前端·javascript·react.js·前端框架·webstorm·antdesignpro
哟哟耶耶4 小时前
js-将JavaScript对象或值转换为JSON字符串 JSON.stringify(this.SelectDataListCourse)
前端·javascript·json