我是MongoDB的一名生成器,正在练习聚合方法。以我为例,我想得到过去5年中生产的葡萄酒(从最新的葡萄酒算起5年(,然后我想统计这段时间内生产了多少葡萄酒(数据库以整数形式给出了葡萄酒的年份(
我相信,首先,我必须按年份对葡萄酒进行分类,然后我应该得到最新葡萄酒的年份,并用五年的时间来计算葡萄酒。但我不知道如何使用聚合代码来编写所有这些。
谢谢!
您需要使用各种聚合管道阶段来转换数据。
MongoDB的聚合框架是基于数据处理管道的概念建模的。文档进入一个多阶段管道,该管道将文档转换为聚合结果。
正如你所提到的,
- 首先你必须得到最新葡萄酒的年份
我使用$group对数据进行分组,$max用于获取newestWineYear
,整个文档($$ROOT(通过使用$push 推送到data
第1阶段
{
$group: {
_id: null,
"newestWineYear": {
$max: "$year"
},
data: {
$push: "$$ROOT"
}
}
}
- 第一阶段的输出包含数组中的所有文档,我们将其命名为
data
和newestWineYear
因此,为了使data
阵列变平,使用$unvent。
阶段2
{
$unwind: "$data"
}
- 获取过去5年生产的葡萄酒数量
我已经使用$group来获得计数,计数是使用$sum获得的。
第3阶段
{
$group: {
_id: null,
count: {
"$sum": {
$cond: [
{
"$gte": [
"$data.year",
{
"$subtract": [
"$newestWineYear",
5
]
}
]
},
1,
0
]
}
}
}
}
在$sum中添加一个条件,仅计算过去5年中生产的葡萄酒。
条件在$cond内可用。
上面写着:
If "data.year" >= [ "$newestWineYear" - 5 ], then add 1 to count, else add 0
之所以使用data.year
,是因为在聚合管道的第一阶段,我们已经将年份葡萄酒推送到了data
阵列中。
最终聚合查询可以在这里找到:游乐场
在这里可以找到另一种方法,$group中没有$cond,但引入了$match阶段,只获得过去5年生产的葡萄酒。
正如您所猜测的,您需要使用mongo的聚合框架。
从一个简单的管道开始,有3个简单的步骤:
- 使用$group分组以获取去年的数据(返回一个数组(
- 移除数组并获取单个文档($unvent运算符(
- 使用$match运算符筛选文档
最后,您可以替换文档的根以获得更好的格式结果。
想象一下,有这样的数据:
[
{
"wine": "Red xxx",
"year": 2018
},
{
"wine": "Red yyy",
"year": 2017
},
{
"wine": "Red zzz",
"year": 2017
},
{
"wine": "White 1",
"year": 2016
},
{
"wine": "White 2",
"year": 2013
},
{
"wine": "White 3",
"year": 2017
},
{
"wine": "White 4",
"year": 2009
}
]
这是管道,你可以在操场上看到结果。
db.collection.aggregate({
$group: {
_id: null,
"lastYear": {
$max: "$year"
},
data: {
$push: "$$ROOT"
}
}
},
{
$unwind: "$data"
},
{
$match: {
$expr: {
$gte: [
"$data.year",
{
"$subtract": [
"$lastYear",
5
]
}
]
}
}
},
{
"$replaceWith": "$data"
})