今天和大家分享mongodb中管道
,老规矩贴上官方 文档
我们从聚合慢慢引入管道的概念
mongo中常见的聚合有count,distinct,group,mapReduce
我们先创建好测试数据,查看一下
> db.student.find().pretty()
{ "_id" : 1, "name" : "tom", "age" : 20, "scores" : 98 }
{ "_id" : 2, "name" : "jack", "age" : 21, "scores" : 89 }
{ "_id" : 3, "name" : "lucy", "age" : 19, "scores" : 91 }
{ "_id" : 4, "name" : "luna", "age" : 21, "scores" : 91 }
下面来介绍个方法的使用
1.count 统计文档数量
> db.student.count() //统计文档数量
4
> db.student.count({"age": {$gte: 20}}) //统计年龄大于等于20的文档数量
3
2.countDocuments
mongo4.0以上的版本已经不推荐使用count
了,取而代之的是countDocuments
> db.student.countDocuments({"age": {$gte: 20}})
3
3.distinct 获取指定字段的值的分布(去重)
> db.student.distinct("scores")
[ 98, 89, 91 ]
4.aggregate(管道)替代group
,老板本mongo是有直接的命令group
来分组的
官方原文
DEPRECATED SINCE VERSION 3.4
Mongodb 3.4 deprecates the
group
command. Usedb.collection.aggregate()
with the$group
stage ordb.collection.mapReduce()
instead.
mongodb3.4版本废弃了group
命令,取而代之的是db.collection.aggregate
和db.collection.mapReduce
> db.student.aggregate([ {$group: {_id: "$scores", person_num : {$sum: "$scores"}}} ])
{ "_id" : 91, "person_num" : 182 }
{ "_id" : 89, "person_num" : 89 }
{ "_id" : 98, "person_num" : 98 }
类似于mysql的
select scores, count(*) as person_num from student group by scores
$sum
后面的是什么意思呢,对scores字段求和
> db.student.aggregate([
{$match: {"name": {$in: ["tom", "jack", "luna"]}}},
{$group: {_id: "$scores", person_num : {$sum: 1}}}
])
{ "_id" : 91, "person_num" : 1 }
{ "_id" : 89, "person_num" : 1 }
{ "_id" : 98, "person_num" : 1 }
这里就是一个典型的管道使用情况了, 以上命令执行了两步,在一个管道里面执行
- 先匹配
name
值在数组["tom", "jack", "luna"]的文档 - 再分组统计
既然说到了分组group
我就顺便再讲几个聚合方法吧
根据年龄分组求平均值实例
> db.student.find()
{ "_id" : 1, "name" : "tom", "age" : 20, "scores" : 98 }
{ "_id" : 2, "name" : "jack", "age" : 21, "scores" : 89 }
{ "_id" : 3, "name" : "lucy", "age" : 19, "scores" : 91 }
{ "_id" : 4, "name" : "luna", "age" : 21, "scores" : 91 }
> db.student.aggregate([{$group : {_id: "$age", avg_scores: {$avg: "$scores"}}}])
{ "_id" : 19, "avg_scores" : 91 }
{ "_id" : 21, "avg_scores" : 90 }
{ "_id" : 20, "avg_scores" : 98 }
根据分数分组,求组内最小的分数
> db.student.aggregate([{$group : {_id: "$scores", min_scores: {$min: "$age"}}}])
{ "_id" : 91, "min_scores" : 19 }
{ "_id" : 89, "min_scores" : 21 }
{ "_id" : 98, "min_scores" : 20 }
对应的$max方法语法一直
总结:
表达式 | 描述 | 语法 |
---|---|---|
$sum | 计算总和 | db.mycol.aggregate([{by_field", alias_name : {field"}}}]) |
$avg | 计算平均值 | db.mycol.aggregate([{by_field", alias_name : {field"}}}]) |
$min | 获取集合中所有文档对应值得最小值 | db.mycol.aggregate([{by_field", alias_name : {field"}}}]) |
$max | 获取集合中所有文档对应值得最大值 | db.mycol.aggregate([{by_field", alias_name : {field"}}}]) |
$by_field
是分组的字段,比如按年龄分组就改成$age
alias_name
是统计数据之后的一个别名,类似于mysql的as
$field
是聚合的字段 比如按年龄分组后取分组中scores的最大值就把$field
改为$scores
管道中的排序
文档的排序也是要通过管道来实现的
> db.student.aggregate([{$sort : {age : 1}}])
{ "_id" : 3, "name" : "lucy", "age" : 19, "scores" : 91 }
{ "_id" : 1, "name" : "tom", "age" : 20, "scores" : 98 }
{ "_id" : 2, "name" : "jack", "age" : 21, "scores" : 89 }
{ "_id" : 4, "name" : "luna", "age" : 21, "scores" : 91 }
官方原文
For the field or fields to sort by, set the sort order to
1
or-1
to specify an ascending or descending sort respectively, as in the following example:
1是升序asc,-1是降序desc
最后说一下管道中的其它操作
-
$project
:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。 -
$match
:用于过滤数据,只输出符合条件的文档。$match
使用MongoDB的标准查询操作。 -
$limit
:用来限制MongoDB聚合管道返回的文档数。 -
$skip
:在聚合管道中跳过指定数量的文档,并返回余下的文档。 -
$unwind
:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。 -
$group
:将集合中的文档分组,可用于统计结果。 -
$sort
:将输入文档排序后输出。 -
$geoNear
:输出接近某一地理位置的有序文档
本文写的有点乱,希望看官不要见怪!!!
网友评论