On this page
$bucket (aggregation)
在本页面
Definition
$bucket- 3.4 版的新功能。
根据指定的表达式和存储段边界将传入文档分类为称为存储段的组。
每个存储段在输出中均表示为文档。每个存储桶的文档包含一个_id字段,其值指定存储桶的包含下限;一个count字段包含该存储桶中的文档数。未指定output时,默认情况下包括count字段。
$bucket仅为包含至少一个 Importing 文档的存储桶生成输出文档。
{
$bucket: {
groupBy: <expression>,
boundaries: [ <lowerbound1>, <lowerbound2>, ... ],
default: <literal>,
output: {
<output1>: { <$accumulator expression> },
...
<outputN>: { <$accumulator expression> }
}
}
}
| Field | Type | Description |
|---|---|---|
groupBy |
expression | expression用于分组文档。要指定field path,请在字段名前加上美元符号$并将其括在引号中。 |
除非$bucket包含default规范,否则每个 Importing 文档都必须将groupBy字段路径或表达式解析为落入boundaries指定的范围之一内的值。
| boundaries | array |基于groupBy表达式的值数组,这些值指定每个存储区的边界。每个相邻的值对都充当存储桶的包含下边界和专有上边界。您必须至少指定两个边界。
指定的值必须按升序排列,并且所有值都相同type。exception 是值是混合数字类型,例如:[ 10, NumberLong(20), NumberInt(30) ]
如果值为文档,则必须将它们包装在$literal运算符中。
Example
[ 0, 5, 10 ]数组创建两个存储桶:
[0,5)的下限为0,上限为5。
> [5,10)的下限为5,上限为10。
|
| default |Literals|可选。一个 Literals,它指定另一个存储桶的_id,该存储桶包含所有groupBy表达式结果不属于boundaries指定的存储桶的文档。
> 如果未指定,则每个 Importing 文档必须将groupBy表达式解析为boundaries指定的存储区范围之一内的值,否则该操作将引发错误。
> default值必须小于最低boundaries值,或大于或等于最高boundaries值。
> default的值可以不同于boundaries中的条目的type。
| output |文档|可选。一个文档,除了_id字段外,它还指定要包含在输出文档中的字段。要指定要包括的字段,您必须使用accumulator expressions。
> <outputfield1>: { <accumulator>: <expression1> },
> ...
> <outputfieldN>: { <accumulator>: <expressionN> }
> 指定output时,默认的count字段不包括在输出文档中。明确指定count表达式作为输出文档的一部分以包含它:
> output: {
> <outputField1>: { <accumulator>: <expression1> },
> ...
> "count": { $sum: 1 }
> }|
Behavior
$bucket至少满足以下条件之一,否则操作会引发错误:
每个 Importing 文档将
groupBy表达式解析为boundaries指定的存储区范围之一内的值,或者为
groupBy值在boundaries之外或与boundaries中的值不同的BSON type的存储桶文档指定default值。
如果groupBy表达式解析为数组或文档,则$bucket使用$sort的比较逻辑将 Importing 文档排列到存储桶中。
Example
考虑包含以下文档的集合artwork:
{ "_id" : 1, "title" : "The Pillars of Society", "artist" : "Grosz", "year" : 1926,
"price" : NumberDecimal("199.99") }
{ "_id" : 2, "title" : "Melancholy III", "artist" : "Munch", "year" : 1902,
"price" : NumberDecimal("280.00") }
{ "_id" : 3, "title" : "Dancer", "artist" : "Miro", "year" : 1925,
"price" : NumberDecimal("76.04") }
{ "_id" : 4, "title" : "The Great Wave off Kanagawa", "artist" : "Hokusai",
"price" : NumberDecimal("167.30") }
{ "_id" : 5, "title" : "The Persistence of Memory", "artist" : "Dali", "year" : 1931,
"price" : NumberDecimal("483.00") }
{ "_id" : 6, "title" : "Composition VII", "artist" : "Kandinsky", "year" : 1913,
"price" : NumberDecimal("385.00") }
{ "_id" : 7, "title" : "The Scream", "artist" : "Munch", "year" : 1893
/* No price*/ }
{ "_id" : 8, "title" : "Blue Flower", "artist" : "O'Keefe", "year" : 1918,
"price" : NumberDecimal("118.42") }
以下操作使用$bucket聚合阶段,根据price将artwork集合安排到存储桶中:
db.artwork.aggregate( [
{
$bucket: {
groupBy: "$price",
boundaries: [ 0, 200, 400 ],
default: "Other",
output: {
"count": { $sum: 1 },
"titles" : { $push: "$title" }
}
}
}
] )
这些存储桶具有以下边界:
[0,200)包含下限
0和上限200。[200,400)包含下限
200和上限400。“其他”是不含价格或价格不在上述范围内的文档的
default存储桶。
该操作返回以下文档:
{
"_id" : 0,
"count" : 4,
"titles" : [
"The Pillars of Society",
"Dancer",
"The Great Wave off Kanagawa",
"Blue Flower"
]
}
{
"_id" : 200,
"count" : 2,
"titles" : [
"Melancholy III",
"Composition VII"
]
}
{
"_id" : "Other",
"count" : 2,
"titles" : [
"The Persistence of Memory",
"The Scream"
]
}
将$ bucket 与$ facet 结合使用
$bucket阶段可用于$facet阶段,以在单个聚合阶段中处理artwork上的多个聚合管道。
以下操作基于artwork和year将artwork中的文档分组到存储桶中:
db.artwork.aggregate( [
{
$facet: {
"price": [
{
$bucket: {
groupBy: "$price",
boundaries: [ 0, 200, 400 ],
default: "Other",
output: {
"count": { $sum: 1 },
"artwork" : { $push: { "title": "$title", "price": "$price" } }
}
}
}
],
"year": [
{
$bucket: {
groupBy: "$year",
boundaries: [ 1890, 1910, 1920, 1940 ],
default: "Unknown",
output: {
"count": { $sum: 1 },
"artwork": { $push: { "title": "$title", "year": "$year" } }
}
}
}
]
}
}
] )
第一个方面按price将 Importing 文档分组。这些存储桶具有以下边界:
[0,200)包含下限
0和上限200。[200,400)包含下限
200和上限400。“其他”,是包含文档的“默认”存储桶,其中没有价格或价格不在上述范围内。
第二个方面按year将 Importing 文档分组。这些存储桶具有以下边界:
[1890,1910)包含下限
1890和上限1910。[1910,1920)包含下限
1910和上限1920。[1920,1940)包含下限
1910和上限1940。“未知”,是“默认”存储桶,其中包含没有超出上述范围的年份或年份的文档。
该操作返回以下文档:
{
"year" : [
{
"_id" : 1890,
"count" : 2,
"artwork" : [
{
"title" : "Melancholy III",
"year" : 1902
},
{
"title" : "The Scream",
"year" : 1893
}
]
},
{
"_id" : 1910,
"count" : 2,
"artwork" : [
{
"title" : "Composition VII",
"year" : 1913
},
{
"title" : "Blue Flower",
"year" : 1918
}
]
},
{
"_id" : 1920,
"count" : 3,
"artwork" : [
{
"title" : "The Pillars of Society",
"year" : 1926
},
{
"title" : "Dancer",
"year" : 1925
},
{
"title" : "The Persistence of Memory",
"year" : 1931
}
]
},
{
// Includes the document without a year, e.g., _id: 4
"_id" : "Unknown",
"count" : 1,
"artwork" : [
{
"title" : "The Great Wave off Kanagawa"
}
]
}
],
"price" : [
{
"_id" : 0,
"count" : 4,
"artwork" : [
{
"title" : "The Pillars of Society",
"price" : NumberDecimal("199.99")
},
{
"title" : "Dancer",
"price" : NumberDecimal("76.04")
},
{
"title" : "The Great Wave off Kanagawa",
"price" : NumberDecimal("167.30")
},
{
"title" : "Blue Flower",
"price" : NumberDecimal("118.42")
}
]
},
{
"_id" : 200,
"count" : 2,
"artwork" : [
{
"title" : "Melancholy III",
"price" : NumberDecimal("280.00")
},
{
"title" : "Composition VII",
"price" : NumberDecimal("385.00")
}
]
},
{
// Includes the document without a price, e.g., _id: 7
"_id" : "Other",
"count" : 2,
"artwork" : [
{
"title" : "The Persistence of Memory",
"price" : NumberDecimal("483.00")
},
{
"title" : "The Scream"
}
]
}
]
}
另请参见$bucketAuto