$bucket
将输入文档按照指定的表达式和边界进行分组,每个分组为一个文档,称为“桶”,每个桶都有一个唯一的_id
,其值为文件桶的下线。每个桶中至少要包含一个输入文档,也就是没有空桶。
使用
语法
{
$bucket: {
groupBy: <表达式>,
boundaries: [ <下边界1>, <下边界2>, ... ],
default: <literal>,
output: {
<output1>: {
<$accumulator 表达式> },
...
<outputN>: {
<$accumulator 表达式> }
}
}
}
groupBy
对文档进行分组的表达式。若指定字段路径,需要在字段名前加上美元符号$
并用引号引起来,如:$field_name
。
除非指定了default
,否则所有输入文档的groupBy的值都必须在boundaries
指定边界的范围内。
boundaries
分组边界数组,数组中相邻的两个值分别作为桶的上下边界,输入文档根据groupBy
表达式的值,确定被分配到哪个桶。数组至少要有两个元素,并按照升序从左到右排列,除数值混合类型外(如:[10, NumberLong(20), NumberInt(30)]
),数组元素类型必须一致。
举例:
一个数组 [ 0, 5, 10 ] 创建了两个桶:
[0,5),下界为 0,上界为 5。
[5,10),下界为 5,上界为 10。
default
可选,指定缺省桶的_id
,不符合boundaries
范围的文档都会放在缺省桶内。如果不指定default
,所有输入文档的groupBy
表达式的值必须落在boundaries
区间,否则会抛出异常。
缺省值必须小于boundaries
数组中最小的值或大于boundaries
数组中的最大值。default
值的类型可以不同于boundaries
数组元素的类型。
out
可选,指定输出文档内容中除_id
字段外要包含的其他字段,指定的字段必须使用汇总(累加器)表达式。
<outputfield1>: {
<accumulator>: <expression1> },
...
<outputfieldN>: {
<accumulator>: <expressionN> }
如果未指定output
文档,默认返回桶内文档数量count
字段,如果指定了output
文档的字段,则只返回_id
和指定的字段,count
字段默认不会输出。
例子
按年分桶并对桶的结果进行筛选
创建artists
集合并插入下面的记录
db.artists.insertMany([
{
"_id" : 1, "last_name" : "Bernard", "first_name" : "Emil", "year_born" : 1868, "year_died" : 1941, "nationality" : "France" },
{
"_id" : 2, "last_name" : "Rippl-Ronai", "first_name" : "Joszef", "year_born" : 1861, "year_died" : 1927, "nationality" : "Hungary" },
{
"_id" : 3, "last_name" : "Ostroumova", "first_name" : "Anna", "year_born" : 1871, "year_died" : 1955, "nationality" : "Russia" },
{
"_id" : 4, "last_name" : "Van Gogh", "first_name" : "Vincent", "year_born" : 1853, "year_died" : 1890, "nationality" : "Holland" },
{
"_id" : 5, "last_name" : "Maurer", "first_name" : "Alfred", "year_born" : 1868, "year_died" : 1932, "nationality" : "USA" },
{
"_id" : 6, "last_name" : "Munch", "first_name" : "Edvard", "year_born" : 1863, "year_died" : 1944, "nationality" : "Norway" },
{