MongoDB管道聚合各阶段示例

本文涉及的产品
云数据库 MongoDB,通用型 2核4GB
简介:

翻译自:blog.mongodb.org


下面我们就来看看几个操作符:


$match



$match的作用是过滤数据,通过设置一个条件,将数据进行筛选过滤,例子:

1
2
3
db.runCommand({ aggregate :  "article" , pipeline : [
{ $match : { author :  "dave"  } }
]});


这相当于将article这个collection中的记录进行筛选,筛选条件是author属性值为dave,其作用其实相当于普通的find命令,如:

1
> db.article.find({ author :  "dave"  });


所以,那这个命令有什么用呢?与find不同,find的结果是直接作为最终数据返回,而$match只是pipeline中的一环,它筛选的结果数据可以再进行下一级的统计操作。


$project


$project命令用于设定数据的筛选字段,就像我们SQL中select需要的字段一样。例子:

1
2
3
4
5
6
7
8
db.runCommand({ aggregate :  "article" , pipeline : [
{ $match : { author :  "dave"  } },
{ $project : {
_id : 0,
author : 1,
tags : 1
}}
]});


上面就是将所有author为dave的记录的author和tags两个字段取出来。(_id:0 表示去掉默认会返回的_id字段)


其实上面这个功能也能用我们平时用的find命令来实现,如:

1
> db.article.find({ author :  "dave"  }, { _id : 0, author : 1, tags : 1);


$unwind


$unwind命令很神奇,他可以将某一个为array类型字段的数据拆分成多条,每一条包含array中的一个属性。 

  
比如你使用下面命令添加一条记录:

1
2
3
4
5
6
7
8
9
10
11
12
db.article.save( {
title :  "this is your title"  ,
author :  "dave"  ,
posted : new  Date (4121381470000) ,
pageViews : 7 ,
tags : [  "fun"  "nasty"  ] ,
comments : [
{ author : "barbara"  , text :  "this is interesting"  } ,
{ author : "jenny"  , text :  "i like to play pinball" , votes: 10 }
],
other : { bar : 14 }
});


这里面tags字段就是一个array。下面我们在这个字段上应用$unwind操作

1
2
3
db.runCommand({ aggregate :  "article" , pipeline : [
{ $unwind :  "$tags"  }
]});


上面命令的意思就是按tags字段来拆分,此命令执行的结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{
"result"  : [
{
"_id"  : ObjectId( "4eeeb5fef09a7c9170df094b" ),
"title"  "this is your title" ,
"author"  "dave" ,
"posted"  : ISODate( "2100-08-08T04:11:10Z" ),
"pageViews"  : 7,
"tags"  "fun" ,
"comments"  : [
{
"author"  "barbara" ,
"text"  "this is interesting"
},
{
"author"  "jenny" ,
"text"  "i like to play pinball" ,
"votes"  : 10
}
],
"other"  : {
"bar"  : 14
}
},
{
"_id"  : ObjectId( "4eeeb5fef09a7c9170df094b" ),
"title"  "this is your title" ,
"author"  "dave" ,
"posted"  : ISODate( "2100-08-08T04:11:10Z" ),
"pageViews"  : 7,
"tags"  "nasty" ,
"comments"  : [
{
"author"  "barbara" ,
"text"  "this is interesting"
},
{
"author"  "jenny" ,
"text"  "i like to play pinball" ,
"votes"  : 10
}
],
"other"  : {
"bar"  : 14
}
}
],
"ok"  : 1
}


我们可以看到,原来的tags字段是一个包含两个元素的数组,通过$unwind命令后,被拆分成两条记录,每一条记录的tags字段是原来数组中的一个元素。


$group


$group命令比较好理解,功能就是按某一个key将key值相同的多条数据组织成一条。

  
比如我们使用下面命令再往article这个collection中写入一条记录,这时候我们就有两条记录了:

1
2
3
4
5
6
7
8
9
10
11
12
db.article.save( {
title :  "this is some other title"  ,
author :  "jane"  ,
posted : new  Date (978239834000) ,
pageViews : 6 ,
tags : [  "nasty"  "filthy"  ] ,
comments : [
{ author : "will"  , text :  "i don't like the color"  } ,
{ author : "jenny"  , text :  "can i get that in green?"  }
],
other : { bar : 14 }
});


我们可以先用上面的$unwind按tags将记录拆成多条,然后再将记录按tags字段重新组织,将同一个tag对应的所有author放在一个array中。只需要像下面这样写:

1
2
3
4
5
6
7
8
db.runCommand({ aggregate :  "article" , pipeline : [
{ $unwind :  "$tags"  },
{ $ group  : {
_id :  "$tags" ,
count  : { $ sum  : 1 },
authors : { $addToSet :  "$author"  }
}}
]});


这时候你就能得到如下结果了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
"result"  : [
{
"_id"  "filthy" ,
"count"  : 1,
"authors"  : [
"jane"
]
},
{
"_id"  "fun" ,
"count"  : 1,
"authors"  : [
"dave"
]
},
{
"_id"  "nasty" ,
"count"  : 2,
"authors"  : [
"jane" ,
"dave"
]
}
],
"ok"  : 1
}


在易用性方面它们提供给我们很多便利,但是MongoDB MapReduce的最大硬伤,单个mongod中无法并行执行,貌似还是没有解决。虽然其命令中采用了pipeline 的组织模式,但是貌似还是完全串行且分降段完成的。

















本文转自UltraSQL51CTO博客,原文链接:http://blog.51cto.com/ultrasql/1661319 ,如需转载请自行联系原作者



相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。   相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
7月前
|
SQL NoSQL 关系型数据库
MongoDB复杂分组聚合查询1
MongoDB复杂分组聚合查询1
416 0
|
17天前
|
JSON NoSQL MongoDB
mongodb导出聚合查询的数据
mongodb导出聚合查询的数据
|
3月前
|
存储 NoSQL MongoDB
MongoDB之索引和聚合
【1月更文挑战第21天】 一、索引 1、说明 2、原理 3、相关操作 3.1、创建索引 3.2、查看集合索引 3.3、查看集合索引大小 3.4、删除集合所有索引(不包含_id索引) 3.5、删除集合指定索引 4、复合索引 二、聚合 1、说明 2、使用
65 0
|
5月前
|
SQL NoSQL Unix
13 MongoDB高级 - 聚合 aggregate
13 MongoDB高级 - 聚合 aggregate
35 0
|
7月前
|
分布式计算 JavaScript 前端开发
MongoDB复杂分组聚合查询3
MongoDB复杂分组聚合查询3
94 0
|
7月前
|
SQL NoSQL 关系型数据库
MongoDB复杂分组聚合查询2
MongoDB复杂分组聚合查询2
85 0
|
8月前
MongoDB-聚合操作$project
什么是聚合操作 • 聚合操作就是通过一个方法完成一系列的操作 • 在聚合操作中, 每一个操作我们称之为一个阶段 • 聚合操作会将上一个阶段处理结果传给下一个阶段继续处理 • 所有阶段都处理完毕会返回一个新的结果集给我们
132 0
|
8月前
MongoDB-聚合操作表达式
字段路径表达式 $<filed>: 使用 $ 来指示字段路径 $<filed>.<sub-field>: 使用 $ 和 . 来指示内嵌文档字段路径
36 0
|
8月前
MongoDB-聚合操作额外配置
allowDiskUse 默认取值是 false, 默认情况下管道阶段占用的内存不能超过 100M,如果超出 100M 就会报错, 如果需要处理的数据比较多, 聚合操作使用的内存可能超过 100M, 那么我们可以将 allowDiskUse 设置为 true 如果 allowDiskUse 设置为 true, 那么一旦 超出 100M 就会将操作的数据写入到临时文件中, 然后再继续操作
74 0
|
8月前
MongoDB-聚合操作$out
聚合管道阶段 $out: 将前面阶段处理完的文档写入一个新的集合
73 0
MongoDB-聚合操作$out