MongoDb 聚合
shaomine:MongoDb聚合
MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。
测试数据
{ "_id" : 1, "name" : "tom", "sex" : "男", "score" : 100, "age" : 34 }
{ "_id" : 2, "name" : "jeke", "sex" : "男", "score" : 90, "age" : 24 }
{ "_id" : 3, "name" : "kite", "sex" : "女", "score" : 40, "age" : 36 }
{ "_id" : 4, "name" : "herry", "sex" : "男", "score" : 90, "age" : 56 }
{ "_id" : 5, "name" : "marry", "sex" : "女", "score" : 70, "age" : 18 }
{ "_id" : 6, "name" : "john", "sex" : "男", "score" : 100, "age" : 31 }
$group分组
$sum
db.people.aggregate([{$group: {_id: '$sex', personCount: {$sum: 1}}}])
返回结果类似下边的:
{ "_id" : "女", "personCount" : 2 }
{ "_id" : "男", "personCount" : 4 }
$push
把文档中某一列对应的所有数据插入值到一个数组中
> db.people.aggregate([{$group: {_id: '$sex', scores: {$push: "$score"}}}])
{ "_id" : "女", "scores" : [ 40, 70 ] }
{ "_id" : "男", "scores" : [ 100, 90, 90, 100 ] }
$addToSet
类似$push,只是会去掉重复
> db.people.aggregate([{$group: {_id: '$sex', scores: {$addToSet: "$score"}}}])
{ "_id" : "女", "scores" : [ 70, 40 ] }
{ "_id" : "男", "scores" : [ 90, 100 ] }
$first
根据资源文档的排序获取第一个文档数据。类似的还有$last
> db.people.aggregate([{$group: {_id: '$sex', firstPerson: {$first: "$score"}}}])
{ "_id" : "女", "firstPerson" : 40 }
{ "_id" : "男", "firstPerson" : 100 }
null全部统计
相当于不分组了
> db.people.aggregate([{$group: {_id: null, scores: {$push: "$score"}}}])
{ "_id" : null, "scores" : [ 100, 90, 40, 90, 70, 100 ] }
类似的操作符
$avg 计算平均值
$max/$min 获取集合中所有文档对应的最大/最小值
涉及到多个项的分组
> db.people.aggregate([{$group: {_id: {sex:"$sex",score:"$score"}, sum: {$sum: 1}}}])
{ "_id" : { "sex" : "女", "score" : 40 }, "sum" : 1 }
{ "_id" : { "sex" : "女", "score" : 70 }, "sum" : 1 }
{ "_id" : { "sex" : "男", "score" : 90 }, "sum" : 2 }
{ "_id" : { "sex" : "男", "score" : 100 }, "sum" : 2 }
常用的其他聚合操作
$project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
$match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
$limit:用来限制MongoDB聚合管道返回的文档数。
$skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
$unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
$group:将集合中的文档分组,可用于统计结果。
$sort:将输入文档排序后输出。
使用示例:利用php的MongoDb拓展,通过cmd实现聚合操作
$cmd = new \MongoDB\Driver\Command([
'aggregate' => 'people',
'pipeline' => [
[
'$project'=>[
'_id'=>0, //选择还是不选择
'newSex'=>'$sex', //重命名
"new"=>"defaultValue", //增加一项
'ageAdded'=>[ //算术运算,得到的新项名字叫ageAdded
'$add'=>['$age',1000]
]
]
],
[
'$match' => [ //筛选
'sex'=>'男'
]
],
[
'$skip' => 1
],
[
'$group' => [
'_id' => null, 'count' => ['$sum' => 1]
]
],
]
]);
$unwind的操作
{
”_id“:1,
”array“:['one','two']
}
然后会得到下边的结果
>db.test.aggregate([{ $unwind : "$array" }])
//得到下边的结果
{"_id":1,"array":"one"},
{"_id":1,"array":"two"}
$lookup操作
可以实现join操作,会把查找到的文档嵌入当前查询结果
{
$lookup:
{
from: <collection to join>,
localField: <field from the input documents>,
foreignField: <field from the documents of the "from" collection>,
as: <output array field>
}
}