Mongodb Mongo DB aggregation按数组字段排序,选择前三条记录并将其他记录合并为一条
我收集了一系列汽车,如下所示:Mongodb Mongo DB aggregation按数组字段排序,选择前三条记录并将其他记录合并为一条,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我收集了一系列汽车,如下所示: cars:[ { "manufacturer": "Skoda", "numbersSold": 40 }, { "manufacturer": "Hyundai", "numbersSold": 90 }, { "manufacturer": "Maruti", "numbersSold": 400 }, {
cars:[
{
"manufacturer": "Skoda",
"numbersSold": 40
},
{
"manufacturer": "Hyundai",
"numbersSold": 90
},
{
"manufacturer": "Maruti",
"numbersSold": 400
},
{
"manufacturer": "VW",
"numbersSold": 15
},
{
"manufacturer": "Mercedez Benz",
"numbersSold": 1
}
]
是否可以在此集合上运行聚合以生成以下结果:
cars:[
{
"manufacturer": "Maruti",
"numbersSold": 400
},
{
"manufacturer": "Hyundai",
"numbersSold": 90
},
{
"manufacturer": "Skoda",
"numbersSold": 40
},
{
"manufacturer": "Other",
"numbersSold": 16
}
]
也就是说,销量最多的前三大制造商和第四大记录应显示为大众和Mercedez-Benz的销量组合值,即15+1,您可以用来实现这一点
问题是:
db.collection.aggregate([
{
$sort: {
"numbersSold": -1
}
},
{
$facet: {
bestThree: [
{
$limit: 3
}
],
others: [
{
$skip: 3
},
{
$addFields: {
manufacturer: "others"
}
},
{
$group: {
_id: null,
manufacturer: {
$first: "$manufacturer"
},
numbersSold: {
$sum: "$numbersSold"
}
}
}
]
}
},
{
$project: {
result: {
$concatArrays: [
"$bestThree",
"$others"
]
}
}
},
{
$unwind: "$result"
},
{
$replaceRoot: {
newRoot: "$result"
}
},
{
$project: {
_id: 0
}
}
])
在阶段结束后,一方面使用获得你的3个最佳结果,另一方面使用其他结果,将这些结果分组并计算总和。
facet之后的最后阶段就是将文档格式化为所需的输出
您可以测试它您可以使用它来实现这一点
问题是:
db.collection.aggregate([
{
$sort: {
"numbersSold": -1
}
},
{
$facet: {
bestThree: [
{
$limit: 3
}
],
others: [
{
$skip: 3
},
{
$addFields: {
manufacturer: "others"
}
},
{
$group: {
_id: null,
manufacturer: {
$first: "$manufacturer"
},
numbersSold: {
$sum: "$numbersSold"
}
}
}
]
}
},
{
$project: {
result: {
$concatArrays: [
"$bestThree",
"$others"
]
}
}
},
{
$unwind: "$result"
},
{
$replaceRoot: {
newRoot: "$result"
}
},
{
$project: {
_id: 0
}
}
])
在阶段结束后,一方面使用获得你的3个最佳结果,另一方面使用其他结果,将这些结果分组并计算总和。
facet之后的最后阶段就是将文档格式化为所需的输出
您可以测试它您可以通过以下查询在5个步骤/阶段中实现:
db.cars.aggregate([
/** Remove _id field in cars collection, which also reduces size of doc a bit by removing a field across all docs */
{ $project: { _id: 0 } },
/** Sort to get top manufacturers */
{ $sort: { numbersSold: -1 } },
/** group to push all manufacturers into an array */
{ $group: { _id: '', cars: { $push: '$$ROOT' } } },
/** project to seperate top 3 manufacturers & others */
{
$project: {
_id: 0, others: [{
$reduce: {
input: { $slice: ["$cars", 3, { $size: '$cars' }] },
initialValue: { numbersSold: 0 },
in: { "manufacturer": 'Other', numbersSold: { $add: ["$$value.numbersSold", "$$this.numbersSold"] } }
}
}], cars: { $slice: ["$cars", 3] }
}
},
/** project to merge top 3 manufacturers & others into one array named cars */
{ $project: { cars: { $concatArrays: ['$cars', '$others'] } } }])
测试:您可以使用以下查询在5个步骤/阶段中实现这一点:
db.cars.aggregate([
/** Remove _id field in cars collection, which also reduces size of doc a bit by removing a field across all docs */
{ $project: { _id: 0 } },
/** Sort to get top manufacturers */
{ $sort: { numbersSold: -1 } },
/** group to push all manufacturers into an array */
{ $group: { _id: '', cars: { $push: '$$ROOT' } } },
/** project to seperate top 3 manufacturers & others */
{
$project: {
_id: 0, others: [{
$reduce: {
input: { $slice: ["$cars", 3, { $size: '$cars' }] },
initialValue: { numbersSold: 0 },
in: { "manufacturer": 'Other', numbersSold: { $add: ["$$value.numbersSold", "$$this.numbersSold"] } }
}
}], cars: { $slice: ["$cars", 3] }
}
},
/** project to merge top 3 manufacturers & others into one array named cars */
{ $project: { cars: { $concatArrays: ['$cars', '$others'] } } }])
测试: