[英]MongoDB aggregation - how to get a percentage value by rate
我正在嘗試獲取有關基於行的所有數據收集的信息
我的數據:
{
_id : 1,
age : 21,
salary : 2500
},
{
_id : 2,
age : 42,
salary : 4300
},
{
_id : 3,
age : 32,
salary : 3100
},
{
_id : 4,
age : 18,
salary : 7000
},
{
_id : 5,
age : 25,
salary : 5600
},
{
_id : 6,
age : 28,
salary : 5200
}
,
{
_id : 7,
age : 38,
salary : 5000
},
{
_id : 8,
age : 28,
salary : 5200
}
我想將值分成四個選項。
第一個選項是 25%。
第二個選項值在 25% 到 50% 之間。
50% 到 75% 之間的第三個選項和
最后一個選項介於 75% 和 100% 之間。
所以當我想拉出一個對象時,它會顯示相對於其他值的值。
例如 :
{
_id : 4,
age : 'less than 25 percent',
salary : 'more than 75 percent'
}
看看這是否符合您的要求。
Mongodb 聚合提供了更多的分析操作來計算數據。 通過$facet
操作,我們可以將多個聚合合二為一。
我們計算salary
和age
最小值/最大值。 然后我們用這個公式計算每個salary
和age
百分比
x − min
---------- x 100
max − min
使用$switch
我們定義了 4 個選項:小於 25、小於 50、小於 75 和更多 han 75
db.collection.aggregate([
{
$facet: {
extremes: [
{
$group: {
_id: null,
maxAge: {
$max: "$age"
},
minAge: {
$min: "$age"
},
maxSalary: {
$max: "$salary"
},
minSalary: {
$min: "$salary"
}
}
}
],
root: [
{
$match: {}
}
]
}
},
{
$set: {
extremes: {
$arrayElemAt: [
"$extremes",
0
]
}
}
},
{
$unwind: "$root"
},
{
$addFields: {
root: {
agePercent: {
$toInt: {
$multiply: [
{
$divide: [
{
$subtract: [
"$root.age",
"$extremes.minAge"
]
},
{
$subtract: [
"$extremes.maxAge",
"$extremes.minAge"
]
}
]
},
100
]
}
},
salaryPercent: {
$toInt: {
$multiply: [
{
$divide: [
{
$subtract: [
"$root.salary",
"$extremes.minSalary"
]
},
{
$subtract: [
"$extremes.maxSalary",
"$extremes.minSalary"
]
}
]
},
100
]
}
}
}
}
},
{
$replaceWith: "$root"
},
{
$project: {
age: {
$switch: {
branches: [
{
case: {$lt: ["$agePercent",25]},
then: "less than 25 percent"
},
{
case: {$lt: ["$agePercent",50]},
then: "less than 50 percent"
},
{
case: {$lt: ["$agePercent",75]},
then: "less than 75 percent"
},
{
case: {$gte: ["$agePercent",75]},
then: "more than 75 percent"
}
],
default: "Unknown"
}
},
salary: {
$switch: {
branches: [
{
case: {$lt: ["$salaryPercent",25]},
then: "less than 25 percent"
},
{
case: {$lt: ["$salaryPercent",50]},
then: "less than 50 percent"
},
{
case: {$lt: ["$salaryPercent",75]},
then: "less than 75 percent"
},
{
case: {$gte: ["$salaryPercent",75]},
then: "more than 75 percent"
}
],
default: "Unknown"
}
}
}
}
])
您可以使用$bucketAuto來做到這一點,默認情況下,它會將集合的所有文檔拆分為最有可能均等指定的 no.of 存儲桶,
腳步 :
age
& 一個salary
,每個數組 4 個子文檔,所有文檔均等地拼接到 4 個存儲桶(子文檔)中。 將每個映射文檔添加到data
數組中。age
和salary
以獲取對象及其特定索引。age
和salary
替換為與其在存儲桶中的位置相對應的文本。data
單個數組。_id
上展開data
數組和$group將唯一文本添加到age
和salary
。age
和salary
是單個元素(字符串)的數組,因此通過使用$arrayElemAt獲取第一個元素將age
和salary
作為字符串類型的字段。詢問 :
db.collection.aggregate([
{
$facet: {
"age": [
{
$bucketAuto: {
groupBy: "$age",
buckets: 4,
output: {
"data": { $push: { '_id': "$$ROOT._id", age: "$$ROOT.age" } }
}
}
}
],
"salary": [
{
$bucketAuto: {
groupBy: "$salary",
buckets: 4,
output: {
"data": { $push: { '_id': "$$ROOT._id", salary: "$$ROOT.salary" } }
}
}
}
]
}
}, { $unwind: { path: '$age', includeArrayIndex: "arrayIndexAge" } },
{ $unwind: { path: '$salary', includeArrayIndex: "arrayIndexSalary" } },
{
$addFields: {
'age.data.age': {
$switch: {
branches: [
{ case: { $eq: ['$arrayIndexAge', 0] }, then: "less than 25 percent" },
{ case: { $eq: ['$arrayIndexAge', 1] }, then: "between 25 and 50 percent" },
{ case: { $eq: ['$arrayIndexAge', 2] }, then: "between 50 and 75 percent" },
{ case: { $eq: ['$arrayIndexAge', 3] }, then: "more than 75 percent" }
]
}
},
'salary.data.salary': {
$switch: {
branches: [
{ case: { $eq: ['$arrayIndexSalary', 0] }, then: "less than 25 percent" },
{ case: { $eq: ['$arrayIndexSalary', 1] }, then: "between 25 and 50 percent" },
{ case: { $eq: ['$arrayIndexSalary', 2] }, then: "between 50 and 75 percent" },
{ case: { $eq: ['$arrayIndexSalary', 3] }, then: "more than 75 percent" }
]
}
}
}
}, { $project: { data: { $concatArrays: ['$age.data', '$salary.data'] } } }, { $unwind: '$data' },
{ $group: { _id: '$data._id', age: { $addToSet: '$data.age' }, salary: { $addToSet: '$data.salary' } } },
{ $addFields: { age: { $arrayElemAt: ['$age', 0] }, salary: { $arrayElemAt: ['$salary', 0] } } }])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.