MongoDB聚合-如何按速率获取百分比值

MongoDB聚合-如何按速率获取百分比值,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我正在尝试获取有关行基所有数据收集的信息 我的数据: { _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

我正在尝试获取有关行基所有数据收集的信息

我的数据:

{
    _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'
}

看看这是否符合您的要求

解释 提供更多的分析操作来计算数据。使用
$facet
操作,我们可以一次计算多个聚合

我们计算
工资
年龄
的最小/最大值。然后,我们计算每个
工资
年龄
的百分比

使用
$switch
我们定义了4个选项:小于25、小于50、小于75和大于75


您可以使用默认情况下会将集合中的所有文档拆分为指定数量最可能相等的存储桶

步骤:

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] } } }])
  • 用于为
    年龄
    工资
    创建一个数组,每个数组包含4个子文档,所有文档平均拼接到4个存储桶(子文档)中。将每个映射文档添加到
    数据
    数组中
  • 展开
    age
    salary
    以取出对象及其特定索引
  • 用于将现有字段
    age
    salary
    替换为与其在bucket中的位置相对应的文本
  • 使用&将两个数组合并到名为
    data
    的单个数组中
  • 展开
    数据
    数组&on
    \u id
    年龄
    工资
    添加唯一文本
  • age
    salary
    是单个元素(字符串)的数组,因此通过使用get-first元素将
    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] } } }])
    

    测试:

    因此,您希望获取返回的所有文档,其中包含
    年龄
    薪资
    字段,以这种方式更新意味着这些文档属于4类中的哪一类?是的,可能吗?
    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] } } }])