Skip to content

聚合查询(分组、聚合、运算)

通过聚合查询,您可以进行数据处理、转换、筛选、统计、排序、分组、联接,支持复杂逻辑运算;注意聚合查询是一个相对复杂的概念。

使用 db.collection(<collection_name>) 对象中的 aggregate 方法,您可以进行聚合查询操作。

操作符
方法描述
$project重命名、增加或删除字段。
$match过滤数据,只返回符合条件的数据。
$group分组聚合操作,对数据进行分组并应用聚合函数。
$sort对数据进行排序。
$limit限制结果集中返回的数据数量。
$skip跳过指定数量的数据,返回剩余的数据。
$unwind展开数组,将数组字段拆分为多个数据,每个数据包含数组中的一个元素。
$group对分组的数据执行累加、求平均值等聚合操作。
$lookup执行左连接,从其他集合中获取匹配的数据。
$addFields增加新的字段到数据中。
$replaceRoot用指定的数据替换结果集中的数据。
$out将结果集写入新的集合。
$facet允许在同一次查询中执行多个独立的聚合操作,并返回多个结果集。
聚合函数
函数描述
$sum计算指定字段的总和。
$avg计算指定字段的平均值。
$min找出指定字段的最小值。
$max找出指定字段的最大值。
$push将指定字段的值添加到数组中。
$addToSet将指定字段的唯一值添加到集合中。
$first返回指定字段的第一个文档值。
$last返回指定字段的最后一个文档值。
$stdDevPop计算指定字段的总体标准差。
$stdDevSamp计算指定字段的样本标准差。
$meta在文本搜索中返回文档的元数据,例如文本匹配的分数。
$size返回数组字段的长度。
$slice从数组中返回指定范围的元素。
$filter根据条件过滤数组中的元素。
$regexMatch使用正则表达式匹配文本字段。
$expr允许在聚合管道中使用表达式。

$match 匹配

js
function main() {
    let query = [
        {
            $match: {
                name: '王华',
            },
        },
    ]
    let result = db.collection('students').aggregate(query) // 查询 students 集合中 name 为 王华 的数据
    if (result == null) {
        return '查询失败'
    }
    return '查询成功:' + JSON.stringify(result)
}
js
function main() {
    let query = [
        {
            $match: {
                name: '王华',
                age: 21,
            },
        },
    ]
    let result = db.collection('students').aggregate(query) // 查询 students 集合中 name 为 王华 并且 age 为 21 的数据
    if (result == null) {
        return '查询失败'
    }
    return '查询成功:' + JSON.stringify(result)
}
js
function main() {
    let query = [
        {
            $match: {
                name: '王华',
                age: { $lt: 18 },
            },
        },
    ]
    let result = db.collection('students').aggregate(query) // 查询 students 集合中 name 为 王华 并且 age 小于 18 的数据
    if (result == null) {
        return '查询失败'
    }
    return '查询成功:' + JSON.stringify(result)
}

$project 重新定义结构

js
function main() {
    let query = [
        {
            $project: { _id: 0, name: 1, age: 1 }, // 0 为排除、1 为包含
        },
    ]
    let result = db.collection('students').aggregate(query) // 只查询 students 集合中的 name 和 age 字段数据
    if (result == null) {
        return '查询失败'
    }
    return '查询成功:' + JSON.stringify(result)
}
js
function main() {
    let query = [
        {
            $match: {
                name: '王华',
                age: { $lt: 18 },
            },
        },
        {
            $project: { _id: 0, name: 1, age: 1 }, // 0 为排除、1 为包含
        },
    ]
    let result = db.collection('students').aggregate(query) // 查询 students 集合中 name 为 王华 并且 age 小于 18 的 name 和 age 字段数据
    if (result == null) {
        return '查询失败'
    }
    return '查询成功:' + JSON.stringify(result)
}

$sum 计算总和

js
function main() {
    let query = [
        {
            $group: {
                _id: '$name',
                count: {
                    $sum: 1,
                },
            },
        },
    ]
    let result = db.collection('students').aggregate(query) // 统计 students 集合中 name 相同的学生数量
    if (result == null) {
        return '查询失败'
    }
    return '查询成功:' + JSON.stringify(result)
}
js
function main() {
    let query = [
        {
            $group: {
                _id: null,
                count: {
                    $sum: '$age',
                },
            },
        },
    ]
    let result = db.collection('students').aggregate(query) // 计算 students 集合中所有学生的年龄总和
    if (result == null) {
        return '查询失败'
    }
    return '查询成功:' + JSON.stringify(result)
}

$avg 计算平均值

js
function main() {
    let query = [
        {
            $group: {
                _id: null,
                avgAge: {
                    $avg: '$age',
                },
            },
        },
    ]
    let result = db.collection('students').aggregate(query) // 计算 students 集合中所有学生的平均年龄
    if (result == null) {
        return '查询失败'
    }
    return '查询成功:' + JSON.stringify(result)
}

$max 计算最大值

js
function main() {
    let query = [
        {
            $group: {
                _id: null,
                maxAge: {
                    $max: '$age',
                },
            },
        },
    ]
    let result = db.collection('students').aggregate(query) // 计算 students 集合中所有学生的最大年龄
    if (result == null) {
        return '查询失败'
    }
    return '查询成功:' + JSON.stringify(result)
}

$min 计算最小值

js
function main() {
    let query = [
        {
            $group: {
                _id: null,
                minAge: {
                    $min: '$age',
                },
            },
        },
    ]
    let result = db.collection('students').aggregate(query) // 计算 students 集合中所有学生的最小年龄
    if (result == null) {
        return '查询失败'
    }
    return '查询成功:' + JSON.stringify(result)
}

一起使用

js
function main() {
    let query = [
        {
            $group: {
                _id: null,
                count: { $sum: '$age' }, // 计算年龄总和
                avgAge: { $avg: '$age' }, // 计算平均年龄
                maxAge: { $max: '$age' }, // 计算最大年龄
                minAge: { $min: '$age' }, // 计算最小年龄
            },
        },
    ]
    let result = db.collection('students').aggregate(query) // 计算 students 集合中所有学生的年龄总和、平均年龄、最大年龄、最小年龄
    if (result == null) {
        return '查询失败'
    }
    return '查询成功:' + JSON.stringify(result)
}

不同分组一起使用

js
function main() {
    let query = [
        {
            $group: {
                _id: '$name',
                avgAge: { $avg: '$age' },
                minAge: { $min: '$age' },
                maxAge: { $max: '$age' },
                count: { $sum: 1 }, // 计算相同姓名的数量
            },
        },
        {
            $group: {
                _id: null,
                totalStudents: { $sum: '$count' },
                avgAge: { $avg: '$avgAge' },
                minAge: { $min: '$minAge' },
                maxAge: { $max: '$maxAge' },
            },
        },
    ]
    let result = db.collection('students').aggregate(query) // 计算 students 集合中所有学生的年龄总和、平均年龄、最大年龄、最小年龄
    if (result == null) {
        return '查询失败'
    }
    return '查询成功:' + JSON.stringify(result)
}

技术支持、市场合作:wwwanghua@outlook.com