Ac562aa3b6f3f3aa37b346fc8d661f4b
mongo 聚合教程及工作应用

聚合的基础教程请看 官方文档: https://docs.mongodb.com/manual/aggregation 基本上都能看懂, 但 mongo 聚合难就难在 对于初学者, 很容易迷失方向, 不知道有什么东西可以用, 以及该如何用。

下面给出例子以及详细解释。

数据已经过我处理脱敏, 背景也做了更改:

  • leftPDSuc, 以及 rightPDSuc, left 和 right 为 true 代表此人是左脚还是右脚患病, 空为不患病;

  • 但只要有一只脚患病, 我们就认为此人是患病了;

  • PD 为具体某一种病, 同理 CR, Celery 也是两种病;

    但因为业务原因, success 相关字段不能用 1 和 0代替, 而只能用 true 和 false, 这给数据查询统计带来了极大的麻烦. 刚开始时, 我被这个问题困扰了很久, 因为1和0就可以简单的用 sum 函数统计起来了..

1、在给出的时间区间内(createdAt字段)查一下各个疾病为true的数量,以及数据的总数;
如果用户并没有传入时间区间,就默认全部的数据。

db.molly.aggregate([
    { $match: { birth: {
        $gt: new ISODate("2012-05-25T02:30:58.937Z"), $lt: new ISODate("2019-05-25T02:30:58.937Z") }
    } },
    {
        $project: {
            PDSuc: { $cond: {
            if: { $or: [ {
                $eq: [true, "$leftPDSuc"]}, {$eq: [true, "$rightPDSuc"]}
            ] }, then: 1, else: 0 } },
            CRSuc: { $cond: {
            if: { $or: [ { $eq: [true, "$leftCRSuc"]}, {$eq: [true, "$rightCRSuc"]} ] },
                then: 1, else: 0 } },
            CelerySuc: { $cond: {
            if: { $or: [ {
                $eq: [true, "$leftCelerySuc"]}, {$eq: [true, "$rightCelerySuc"]}
            ] }, then: 1, else: 0 } },
        },
    },
    { $group: { _id: null,
        all_PDSuc: { $sum: "$PDSuc" }, all_CRSuc: { $sum: "$CRSuc"},
        all_CelerySuc: { $sum: "$CelerySuc" },
    }
    },
] )

幸好, 我们有$project, 可以把 旧字段挑选出来, 或者重新新增一个字段, 给下一个 aggregate 的 pipeline 处理。

注意上面, 我把 leftPDSucrightPDSuc 判断是否存在有一个为 true, 是的话, 就赋值1给新字段PDSuc, 否就是0. 借此, 我们就可以知道这个人是否患有这个病了.
然后通过 $group$sum, 就可以把 总数算出来了。

为什么_id 为 null 呢?

null to calculate accumulated values for all the input documents as a whole.

null 用来把全部文档当做整体来运算, 所以就可以用 $sum

2、根据前端给出的性别字段(三大类:男、女、未知),查一下各个性别下 各个疾病的数量,以及数据的总数
```
db.molly.aggregate([
{
$project: {
PDSuc: { $cond: {
if: { $or: [ {
$eq: [true, "$leftPDSuc"]}, {$eq: [true, "$rightPDSuc"]}
] }, then: 1, else: 0 } },
CRSuc: { $cond: {
if: { $or: [ { $eq: [true, "$leftCRSuc"]}, {$eq: [true, "$rightCRSuc"]} ] },
then: 1, else: 0 } },
CelerySuc: { $cond: {
if: { $or: [ {
$eq: [true, "$leftCelerySuc"]}, {$eq: [true, "$rightCelerySuc"]}
] }, then: 1, else: 0 } },
gender: "$gender",
},

top Created with Sketch.