MongoDB聚合,按值间隔分组,
MongoDB文件:MongoDB聚合,按值间隔分组,,mongodb,aggregation-framework,Mongodb,Aggregation Framework,MongoDB文件: [{ _id: '123213', elevation: 2300, area: 25 }, { _id: '343221', elevation: 1600, area: 35, }, { _id: '545322', elevation: 500 area: 12, }, { _id: '234234', elevation: null, area: 5 }] 我想按给定的标高间隔对这些属性进行分组,并总结面积属性 第
[{
_id: '123213',
elevation: 2300,
area: 25
},
{
_id: '343221',
elevation: 1600,
area: 35,
},
{
_id: '545322',
elevation: 500
area: 12,
},
{
_id: '234234',
elevation: null,
area: 5
}]
我想按给定的标高间隔对这些属性进行分组,并总结面积属性
- 第1组:<0
- 第2组:0-1500
- 第三组:1501-3000
- 第4组:>3000
[{
interval: '1501-3000',
count: 2,
summarizedArea: 60
},
{
interval: '0-1500',
count: 1,
summarizedArea: 12,
},
{
interval: 'N/A',
count: 1,
summarizedArea: 5
}]
如果可能,我想使用聚合管道
可能是
$range
?或者是$gte
和$lte
的组合?您可以使用MongoDB 3.4中引入的$bucket
来实现这一点:
db.collection.aggregate([
{
$bucket: {
groupBy: "$elevation",
boundaries: [
0,
1500,
3000,
5000
],
default: 10000,
output: {
"count": {
$sum: 1
},
"summarizedArea": {
$sum: "$area"
}
}
}
}
])
输出:
[
{
"_id": 0,
"count": 1,
"summarizedArea": 12
},
{
"_id": 1500,
"count": 2,
"summarizedArea": 60
},
{
"_id": 10000,
"count": 1,
"summarizedArea": 5
}
]
您可以在这里尝试:您可以使用MongoDB 3.4中引入的
$bucket
来实现以下目标:
db.collection.aggregate([
{
$bucket: {
groupBy: "$elevation",
boundaries: [
0,
1500,
3000,
5000
],
default: 10000,
output: {
"count": {
$sum: 1
},
"summarizedArea": {
$sum: "$area"
}
}
}
}
])
输出:
[
{
"_id": 0,
"count": 1,
"summarizedArea": 12
},
{
"_id": 1500,
"count": 2,
"summarizedArea": 60
},
{
"_id": 10000,
"count": 1,
"summarizedArea": 5
}
]
您可以在这里尝试:正如Feliix建议的那样,应该完成这项工作,但是边界应该稍有不同,以便更好地处理负值和N/A
值:
db.collection.aggregate([
{
$bucket: {
groupBy: "$elevation",
boundaries: [ -Number.MAX_VALUE, 0, 1501, 3001, Number.POSITIVE_INFINITY ],
default: Number.NEGATIVE_INFINITY,
output: {
"count": { $sum: 1 },
"summarizedArea" : { $sum: "$area" }
}
}
}
])
可以将下面的格式化阶段添加到管道中,以调整响应的形状:
{ $group: {
_id: null,
documents: { $push: {
interval: { $let: {
vars: {
idx: { $switch: {
branches: [
{ case: { $eq: [ "$_id", -Number.MAX_VALUE ] }, then: 3 },
{ case: { $eq: [ "$_id", 0 ] }, then: 2 },
{ case: { $eq: [ "$_id", 1501 ] }, then: 1 },
{ case: { $eq: [ "$_id", 3001 ] }, then: 0 }
],
default: 4
} }
},
in: { $arrayElemAt: [ [ ">3000", "1501-3000", "0-1500", "<0", "N/A" ], "$$idx" ] }
} },
count: "$count",
summarizedArea: "$summarizedArea"
} }
} }
{$group:{
_id:null,
文档:{$push:{
间隔:{$let:{
变量:{
idx:{$switch:{
分支机构:[
{case:{$eq:[“$\u id”,-Number.MAX\u VALUE]},然后:3},
{case:{$eq:[“$\u id”,0]},然后:2},
{case:{$eq:[“$_id”,1501]},然后:1},
{case:{$eq:[“$\u id”,3001]},然后:0}
],
默认值:4
} }
},
在:{$arrayElemAt:[[”>3000、“1501-3000”、“0-1500”、“3000”、“1501-3000”、“0-1500”中,正如Feliix所建议的那样,“应该完成这项工作,但边界应该略有不同,以便更好地处理负值和N/A
值:
db.collection.aggregate([
{
$bucket: {
groupBy: "$elevation",
boundaries: [ -Number.MAX_VALUE, 0, 1501, 3001, Number.POSITIVE_INFINITY ],
default: Number.NEGATIVE_INFINITY,
output: {
"count": { $sum: 1 },
"summarizedArea" : { $sum: "$area" }
}
}
}
])
可以将下面的格式化阶段添加到管道中,以调整响应的形状:
{ $group: {
_id: null,
documents: { $push: {
interval: { $let: {
vars: {
idx: { $switch: {
branches: [
{ case: { $eq: [ "$_id", -Number.MAX_VALUE ] }, then: 3 },
{ case: { $eq: [ "$_id", 0 ] }, then: 2 },
{ case: { $eq: [ "$_id", 1501 ] }, then: 1 },
{ case: { $eq: [ "$_id", 3001 ] }, then: 0 }
],
default: 4
} }
},
in: { $arrayElemAt: [ [ ">3000", "1501-3000", "0-1500", "<0", "N/A" ], "$$idx" ] }
} },
count: "$count",
summarizedArea: "$summarizedArea"
} }
} }
{$group:{
_id:null,
文档:{$push:{
间隔:{$let:{
变量:{
idx:{$switch:{
分支机构:[
{case:{$eq:[“$\u id”,-Number.MAX\u VALUE]},然后:3},
{case:{$eq:[“$\u id”,0]},然后:2},
{case:{$eq:[“$_id”,1501]},然后:1},
{case:{$eq:[“$\u id”,3001]},然后:0}
],
默认值:4
} }
},
在:{$arrayElemAt:[[[]>3000”,“1501-3000”,“0-1500”,“3000”,“1501-3000”,“0-1500”,“是否有可能使$project作为问题输出?@Per,我肯定是它的,但是你能定义“作为问题”?是间隔标签吗(顺便说一句,它们在问题中看起来是错误的),带有数组而不是光标的单个文档,或文档的特定顺序?不是单个文档。每个组都有一个数组。带有间隔标签。顺序不重要。@抱歉,我没有得到它。它或者是带有组数组的单个文档:[{interval:'1501-3000'…},{interval:'0-1500'…}]
或一个完全没有数组的文档光标:{interval:'1501-3000'…},{interval:'0-1500'…}…
@Per,也是关于标签的。假设高程
总是整数是公平的吗?有可能让$project将其输出为有问题的吗?@Per,我肯定是有问题的,但您能定义“有问题的”吗?是间隔标签(顺便说一句,他们在问题中看起来是错误的)、带有数组而不是光标的单个文档,还是文档的特定顺序?不是单个文档。每个组都有一个数组。带有间隔标签。顺序不重要。@抱歉,我没有理解它。它是带有组数组的单个文档:[{interval:'1501-3000'..},{interval:'0-1500'..}…]
或者一个没有数组的文档光标:{interval:'1501-3000'..},{interval:'0-1500'..}…
@Per,也关于标签。假设高程
总是整数是否公平?