乐趣区

关于mongodb:MongoDB聚合aggregate常用操作及示例

简介

MongoDB 中聚合 (aggregate) 次要用于解决数据(诸如统计平均值,求和等),并返回计算后的数据后果。

有点相似 SQL 语句中的 count(*)

罕用操作

表达式 形容
$match 用于过滤数据,只输入符合条件的文档。$match 应用 MongoDB 的规范查问操作。
$project 批改输出文档的构造。能够用来重命名、减少或删除域,也能够用于创立计算结果以及嵌套文档。
$limit 用来限度 MongoDB 聚合管道返回的文档数。
$skip 在聚合管道中跳过指定数量的文档,并返回余下的文档。
$unwind 将文档中的某一个数组类型字段拆分成多条,每条蕴含数组中的一个值。
$group 将汇合中的文档分组,可用于统计后果。
$sort 将输出文档排序后输入。
$lookup 联表查问
$geoNear 输入靠近某一地理位置的有序文档。
$facet/$bucket 分类搜寻(MongoDB 3.4 以上反对)

 

示例

$match

// 查问条件 以某个分组查问(能够多个查问条件累加到 match 外面)db.getCollection('doc_views').aggregate([
    {$match: { "orgName" : "前端技术部"}
    }
])
// 查问后果如下
/* 1 */
{"_id" : ObjectId("5fcb2c6cdfebd2682b2ae01b"),
    "__v" : 0,
    "time" : "2020-11-11",
    "docName" : "testPublishAll",
    "orgGroup" : "汽车事业群",
    "orgName" : "前端技术部",
    "count" : 3
}
...

$project

// 删减字段
db.getCollection('doc_views').aggregate([
    {$match: { "orgName" : "前端技术部"}
    },
    {
        $project: {
            docName: true,
            orgName: true
        }
    }
])
// 查问后果如下 只显示设置为 true 的字段
/* 1 */
{"_id" : ObjectId("5fcb2c6cdfebd2682b2ae01b"),
    "docName" : "testPublishAll",
    "orgName" : "前端技术部"
}
...
// 定义别名 把 orgGroup 指定指定成 count 字段
db.getCollection('doc_views').aggregate([
    {$match: { "orgName" : "前端技术部"}
    },
    {
        $project: {
            docName: true,
            orgName: true,
            orgGroup: "$count"
        }
    }
])
// 查问后果 orgGroup 字段展现 count 的值
/* 1 */
{"_id" : ObjectId("5fcb2c6cdfebd2682b2ae01b"),
    "docName" : "testPublishAll",
    "orgName" : "前端技术部",
    "orgGroup" : 3
}

$group

// 聚合条件 _id:强制必须存在。db.getCollection('doc_views').aggregate([
    {
        $group: {_id: { name: "$docName", orgName: "$orgName"},
           total: {$sum: "$count"} 
        }
    }
    
])
//1、_id: null  _id 为 null 的查问后果
/* 1 */
{
    "_id" : null,
    "total" : 474
}
//2、_id: "$docName" _id 为某字段
/* 1 */
{
    "_id" : "gch-gitbook",
    "total" : 8
}
...
//3、_id: {name: "$docName", orgName: "$orgName"} _id 查问条件并为字段定义别名
/* 1 */
{
    "_id" : {
        "name" : "vuepress-hjw-test",
        "orgName" : "前端技术部"
    },
    "total" : 2
}

$sort、$skip、$limit

// 列表分页的时候个别三个联结应用来做数据分页
//sort 列表排序 skip 指定跳过多少条 limit 每次查问条数
//skip 的计算形式:(以后页码 -1)* 每页大小 如:(pageIndex - 1) * pageSize
db.getCollection('doc_views').aggregate([{$sort: {_id: -1}},
    {$skip:Number(100)},
    {$limit:Number(10)} 
])
// 查问后果如下
/* 1 */
{"_id" : ObjectId("604ecc57b3b65a411b5600de"),
    "__v" : 0,
    "time" : "2021-02-25",
    "docName" : "abgFeedback",
    "docType" : "vuepress",
    "orgGroup" : "汽车事业群",
    "orgName" : "前端技术部",
    "count" : 1
}

/* 2 */
{"_id" : ObjectId("604ecc57b3b65a411b5600dd"),
    "__v" : 0,
    "time" : "2021-02-24",
    "docName" : "testtestdocs",
    "docType" : "docsify",
    "orgGroup" : "汽车事业群",
    "orgName" : "前端技术部",
    "count" : 1
}

$lookup

// 联表查问
db.getCollection('doc_views').aggregate([{$sort: {_id: -1}},
    {$skip:Number(100)},
    {$limit:Number(10)},
    {$lookup:{
        from: "docs",
        localField: "docName",
        foreignField: "name",
        as: "child"
    }}
])
// 查问后果
/* 1 */
{"_id" : ObjectId("604ecc57b3b65a411b5600de"),
    "__v" : 0,
    "time" : "2021-02-25",
    "docName" : "abgFeedback",
    "docType" : "vuepress",
    "orgGroup" : "汽车事业群",
    "orgName" : "前端技术部",
    "count" : 1,
    "child" : [ 
        {"_id" : ObjectId("5f6da851a18a783210da7a16"),
            "docType" : "vuepress",
            "name" : "abgFeedback",
            "description" : "二手车问题反馈收集问题",
            "owner" : "gongchenghui",
            "orgGroup" : "汽车事业群",
            "orgName" : "前端技术部",
            "newGit" : false,
            "toTop" : ISODate("2020-11-20T02:41:33.742Z"),
            "realName" : "龚成辉",
            "dest" : "abgFeedback",
            "opendFiles" : [],
            "createTime" : ISODate("2020-09-25T08:20:33.373Z")
        }
    ]
}

$facet 分类查问

// 依据条件 分类一次查问出想要的数据和数据的总数
db.getCollection('doc_views').aggregate([{$match: {"orgName" : "前端技术部"}},
    {
        $facet: {
            respData: [{$sort: {_id: -1}},
                {$skip:Number(100)},
                {$limit:Number(1)},
            ],
            total: [
                {$count: "total"}
            ]
        }
    }
// 查问后果如下
  /* 1 */
{
    "respData" : [ 
        {"_id" : ObjectId("604ecc57b3b65a411b5600de"),
            "__v" : 0,
            "time" : "2021-02-25",
            "docName" : "abgFeedback",
            "docType" : "vuepress",
            "orgGroup" : "汽车事业群",
            "orgName" : "前端技术部",
            "count" : 1
        }
    ],
    "total" : [ 
        {"total" : 284}
    ]
}

留神:此办法只能在 3.4 以上版本的数据库中应用,低版本的话还是做两次查问

退出移动版