MongoDb进阶实践之八 MongoDB的聚合初探
一、引言
好久没有写东西了,MongoDB系列的文章也丢下好长时间了。今天终于有时间了,就写了一篇有关聚合的文章。一说到“聚合”,用过关系型数据库的人都应该知道它是一个什么东西。关系型数据库有“聚合”的概念,我们的MongoDB数据库也有聚合的概念,今天我就来抛砖引玉,简单的说一说MongoDB文档数据库中的“聚合”的概念。
二、简介
管道是MongoDB2.2版本引入新的功能 ,它是数据聚合的一个新框架,其概念类似于数据处理的管道。 每个文档通过一个由多个节点组成的管道,每个节点有自己特殊的功能(分组、过滤等),文档经过管道处理后,最后输出相应的结果。管道基本的功能有两个:一是对文档进行“过滤”,也就是筛选出符合条件的文档;二是对文档进行“变换”,也就是改变文档的输出形式。其他的一些功能还包括按照某个指定的字段分组和排序等。而且在每个阶段还可以使用表达式操作符计算平均值和拼接字符串等相关操作。管道提供了一个MapReduce 的替代方案,MapReduce使用相对来说比较复杂,而管道拥有固定的接口(操作符表达),使用比较简单,对于大多数的聚合任务管道一般来说是首选方法。
三、管道的相关操作
管道操作符作为“键”,所对应的“值”叫做管道表达式。它可以看做是管道操作符的操作数(Operand),每个管道表达式是一个文档结构,它是由字段名、字段值、和一些表达式操作符组成的,
每个管道表达式只能作用于处理当前正在处理的文档,而不能进行跨文档的操作。管道表达式对文档的处理都是在内存中进行的。除了能够进行累加计算的管道表达式外,其他的表达式都是无状态的,也就是不会保留上下文的信息。累加性质的表达式操作符通常和$group操作符一起使用,来统计该组内最大值、最小值等,例如上面的例子中我们在$group管道操作符中使用了具有累加的$sum来计算总和。
1、管道表达式使用详解
语法:aggregate() 方法的基本语法格式如下所示:
>db.collectionName.aggregate(aggregateOperation)
参数说明:
collectionName:该参数表示的是集合的名称,就是在哪个集合上进行聚合操作。
aggregateOperation:具体索要执行的聚合操作的名称
下面列出了一些聚合的管道表达式:
表达式 描述 实例
$sum 计算总和。 db.users.aggregate([{$group : {_id : "$author", num_tutorial : {$sum : "$likes"}}}])
$avg 计算平均值 db.users.aggregate([{$group : {_id : "$author", num_tutorial : {$avg : "$likes"}}}])
$min 获取集合中所有文档对应值得最小值。 db.users.aggregate([{$group : {_id : "$author", num_tutorial : {$min : "$likes"}}}])
$max 获取集合中所有文档对应值得最大值。 db.users.aggregate([{$group : {_id : "$author", num_tutorial : {$max : "$likes"}}}])
$push 在结果文档中插入值到一个数组中。 db.users.aggregate([{$group : {_id : "$author", url : {$push: "$url"}}}])
$addToSet 在结果文档中插入值到一个数组中,但不创建副本。 db.users.aggregate([{$group : {_id : "$author", url : {$addToSet : "$url"}}}])
$first 根据资源文档的排序获取第一个文档数据。 db.users.aggregate([{$group : {_id : "$author", first_url : {$first : "$url"}}}])
$last 根据资源文档的排序获取最后一个文档数据 db.users.aggregate([{$group : {_id : "$author", last_url : {$last : "$url"}}}])
1.1、【 $sum】 的用法
//原始数据:
> db.users.find()
{ "_id" : ObjectId("5b1e044733091e826f7c2c74"), "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c75"), "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c76"), "title" : "Log4Net Overrivew", "description" : "log4net is not sql database", "author" : "lingChong", "url" : "http://www.linchong.com", "tags" : [ "log", "net", "NoSQL" ], "likes" : }
> 】、类似sql语句: select author, count(*) from users group by author > db.users.aggregate([{$group:{"_id":"$author","books":{$sum:}}}]);
{ "_id" : "lingChong", "books" : }
{ "_id" : "huangFeiHong", "books" : } 】、类似sql语句: select count() as count from users > db.users.count(); > db.users.aggregate([{$group:{"_id":null,count:{"$sum":}}}]);
{ "_id" : null, "count" : } 】、类似sql语句: select sum(likes) as total from users > db.users.aggregate([{$group:{"_id":null,"total":{"$sum":"$likes"}}}])
{ "_id" : null, "total" : } 类似sql语句: select author,sum(likes) as total from users group by author > db.users.aggregate([{$group:{"_id":"$author","total":{"$sum":"$likes"}}}])
{ "_id" : "lingChong", "total" : }
{ "_id" : "huangFeiHong", "total" : }
1.2、【 $max】 的用法
//原始数据:
> db.users.find()
{ "_id" : ObjectId("5b1e044733091e826f7c2c74"), "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c75"), "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c76"), "title" : "Log4Net Overrivew", "description" : "log4net is not sql database", "author" : "lingChong", "url" : "http://www.linchong.com", "tags" : [ "log", "net", "NoSQL" ], "likes" : }
> 】、类似sql语句: select author, max(likes) from users group by author,我们通过相同的作者来进行分组,然后查询相同作者的书最多的阅读详情 > db.users.aggregate([{$group:{"_id":"$author","max":{"$max":"$likes"}}}]);
{ "_id" : "lingChong", "max" : }
{ "_id" : "huangFeiHong", "max" : }
1.3、【 $min】 的用法
//原始数据:
> db.users.find()
{ "_id" : ObjectId("5b1e044733091e826f7c2c74"), "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c75"), "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c76"), "title" : "Log4Net Overrivew", "description" : "log4net is not sql database", "author" : "lingChong", "url" : "http://www.linchong.com", "tags" : [ "log", "net", "NoSQL" ], "likes" : }
> 】、类似sql语句: select author, min(likes) from users group by author,我们通过相同的作者来进行分组,然后查询相同作者的书最少的阅读详情 > db.users.aggregate([{$group:{"_id":"$author","min":{"$min":"$likes"}}}]);
{ "_id" : "lingChong", "min" : }
{ "_id" : "huangFeiHong", "min" : }
1.4、【 $avg】 的用法
//原始数据:
> db.users.find()
{ "_id" : ObjectId("5b1e044733091e826f7c2c74"), "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c75"), "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c76"), "title" : "Log4Net Overrivew", "description" : "log4net is not sql database", "author" : "lingChong", "url" : "http://www.linchong.com", "tags" : [ "log", "net", "NoSQL" ], "likes" : }
> 】、类似sql语句: select author, avg(likes)as average from users group by author,我们可以根据相同的作者分类算出相同作者阅读数量的平均值 > db.users.aggregate([{$group:{"_id":"$author","average":{"$avg":"$likes"}}}])
{ "_id" : "lingChong", "average" : }
{ "_id" : "huangFeiHong", "average" : } 】、类似sql语句: select avg(likes)as average from users > db.users.aggregate([{$group:{"_id":null,"average":{"$avg":"$likes"}}}])
{ "_id" : null, "average" : 286.6666666666667 }
>
1.5、【 $push】 的用法,将指定的表达式的值添加到一个数组中,就算是有重复的值也会显示,这个值不要超过16M,不然会出现错误
//原始数据:
> db.users.find()
{ "_id" : ObjectId("5b1e044733091e826f7c2c74"), "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c75"), "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c76"), "title" : "Log4Net Overview", "description" : "log4net is not sql database", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "log", "net", "NoSQL" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c77"), "title" : "MongoDb Higher", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c78"), "title" : "NoSql Redis Overview", "description" : "No sql database is very fast", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "redis", "database", "NoSql" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c79"), "title" : "Memcached Overrivew", "description" : "Memcached is sql database", "author" : "wuSong", "url" : "http://www.wusong.com", "tags" : [ "memcached", "cache", "NoSQL" ], "likes" : , "quantity" : } 】、我们通过相同的作者来进行分组,然后查询每个相同作者卖出的数量放在数组里面 db.users.aggregate({$group:{"_id":"$author","quantities":{"$push":"$quantity"}}});
{ "_id" : "wuSong", "quantities" : [ ] }
{ "_id" : "linChong", "quantities" : [ , ] }
{ "_id" : "huangFeiHong", "quantities" : [ , , ] } 】、我们通过相同的作者来进行分组,然后查询每个相同作者卖出的数量放在数组里面,并且显示书名和其销量 > db.users.aggregate({$group:{"_id":"$author","quantities":{"$push":{"quantity":"$quantity","title":"$title"}}}});
{ "_id" : "wuSong", "quantities" : [ { "quantity" : , "title" : "Memcached Overrivew" } ] }
{ "_id" : "linChong", "quantities" : [ { "quantity" : , "title" : "Log4Net Overview" }, { "quantity" : , "title" : "NoSql Redis Overview" } ] }
{ "_id" : "huangFeiHong", "quantities" : [ { "quantity" : , "title" : "MongoDb Overview" }, { "quantity" : , "title" : "NoSql Overview" }, { "quantity" : , "title" : "MongoDb Higher" } ] }
> 】、我们通过相同的作者来进行分组,然后查询每个相同作者卖出的数量放在数组里面,并且显示书名和其销量,有重复值,也会显示【{ "quantity" : , "title" : "MongoDb Overview" },{ "quantity" : , "title" : "MongoDb Higher" }】 > db.users.aggregate({$group:{"_id":"$author","quantities":{"$push":{"quantity":"$quantity","title":"$title"}}}});
{ "_id" : "wuSong", "quantities" : [ { "quantity" : , "title" : "Memcached Overrivew" } ] }
{ "_id" : "linChong", "quantities" : [ { "quantity" : , "title" : "Log4Net Overview" }, { "quantity" : , "title" : "NoSql Redis Overview" } ] }
{ "_id" : "huangFeiHong", "quantities" : [ { "quantity" : , "title" : "MongoDb Overview" }, { "quantity" : , "title" : "NoSql Overview" }, { "quantity" : , "title" : "MongoDb Higher" } ] }
>
1.6、【 $addToSet】 的用法,将表达式的值添加到一个数组中(无重复值),这个值不要超过16M,不然会出现错误
//原始数据:
> db.users.find()
{ "_id" : ObjectId("5b1e044733091e826f7c2c74"), "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c75"), "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c76"), "title" : "Log4Net Overview", "description" : "log4net is not sql database", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "log", "net", "NoSQL" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c77"), "title" : "MongoDb Higher", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c78"), "title" : "NoSql Redis Overview", "description" : "No sql database is very fast", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "redis", "database", "NoSql" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c79"), "title" : "Memcached Overrivew", "description" : "Memcached is sql database", "author" : "wuSong", "url" : "http://www.wusong.com", "tags" : [ "memcached", "cache", "NoSQL" ], "likes" : , "quantity" : } 】、我们通过相同的作者来进行分组,然后查询每个相同作者卖出的数量放在数组里面,有重复值,只显示一个4,【{ "_id" : "huangFeiHong", "quantities" : [ , ] } 】 > db.users.aggregate({$group:{"_id":"$author","quantities":{"$addToSet":"$quantity"}}});
{ "_id" : "wuSong", "quantities" : [ ] }
{ "_id" : "linChong", "quantities" : [ , ] }
{ "_id" : "huangFeiHong", "quantities" : [ , ] } 】、我们通过相同的作者来进行分组,然后查询每个相同作者卖出的数量放在数组里面,并且显示书名和其销量 > db.users.aggregate({$group:{"_id":"$author","quantities":{"$addToSet":{"quantity":"$quantity","title":"$title"}}}});
{ "_id" : "wuSong", "quantities" : [ { "quantity" : , "title" : "Memcached Overrivew" } ] }
{ "_id" : "linChong", "quantities" : [ { "quantity" : , "title" : "NoSql Redis Overview" }, { "quantity" : , "title" : "Log4Net Overview" } ] }
{ "_id" : "huangFeiHong", "quantities" : [ { "quantity" : , "title" : "MongoDb Higher" }, { "quantity" : , "title" : "NoSql Overview" }, { "quantity" : , "title" : "MongoDb Overview" } ] }
>
1.7、【 $first】 的用法,返回每组第一个文档,如果有排序,按照排序,如果没有按照默认的存储的顺序的第一个文档。
//原始数据:
> db.users.find()
{ "_id" : ObjectId("5b1e044733091e826f7c2c74"), "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c75"), "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c76"), "title" : "Log4Net Overview", "description" : "log4net is not sql database", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "log", "net", "NoSQL" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c77"), "title" : "MongoDb Higher", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c78"), "title" : "NoSql Redis Overview", "description" : "No sql database is very fast", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "redis", "database", "NoSql" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c79"), "title" : "Memcached Overrivew", "description" : "Memcached is sql database", "author" : "wuSong", "url" : "http://www.wusong.com", "tags" : [ "memcached", "cache", "NoSQL" ], "likes" : , "quantity" : }
> 】、按作者进行分组,获取分组的第一条记录 > db.users.aggregate({"$group":{"_id":"$author","quantityFrist":{"$first":"$quantity"}}})
{ "_id" : "wuSong", "quantityFrist" : }
{ "_id" : "linChong", "quantityFrist" : }
{ "_id" : "huangFeiHong", "quantityFrist" : }
1.8、【 $last】 的用法,返回每组最后一个文档,如果有排序,按照排序,如果没有按照默认的存储的顺序的最后个文档。
//原始数据:
> db.users.find()
{ "_id" : ObjectId("5b1e044733091e826f7c2c74"), "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c75"), "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c76"), "title" : "Log4Net Overview", "description" : "log4net is not sql database", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "log", "net", "NoSQL" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c77"), "title" : "MongoDb Higher", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c78"), "title" : "NoSql Redis Overview", "description" : "No sql database is very fast", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "redis", "database", "NoSql" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c79"), "title" : "Memcached Overrivew", "description" : "Memcached is sql database", "author" : "wuSong", "url" : "http://www.wusong.com", "tags" : [ "memcached", "cache", "NoSQL" ], "likes" : , "quantity" : }
> 】、按作者进行分组,获取分组的最后一条记录 > db.users.aggregate({"$group":{"_id":"$author","quantityLast":{"$last":"$quantity"}}})
{ "_id" : "wuSong", "quantityLast" : }
{ "_id" : "linChong", "quantityLast" : }
{ "_id" : "huangFeiHong", "quantityLast" : }
2、管道操作符使用详解
管道是由一个个功能节点组成的,这些节点用管道操作符来进行表示。聚合管道以一个集合中的所有文档作为开始,然后这些文档从一个操作节点流向下一个节点 ,每个操作节点对文档做相应的操作。这些操作可能会创建新的文档或者过滤掉一些不符合条件的文档,在管道中可以对文档进行重复操作。管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。 MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。
表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。
2.1、【$project】:数据投影,主要用于重命名、增加和删除字段,也可以用于创建计算结果以及嵌套文档。
//原始数据
> db.users.find({},{_id:})
{ "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "Log4Net Overview", "description" : "log4net is not sql database", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "log", "net", "NoSQL" ], "likes" : , "quantity" : }
{ "title" : "MongoDb Higher", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "NoSql Redis Overview", "description" : "No sql database is very fast", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "redis", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "Memcached Overrivew", "description" : "Memcached is sql database", "author" : "wuSong", "url" : "http://www.wusong.com", "tags" : [ "memcached", "cache", "NoSQL" ], "likes" : , "quantity" : }
> //隐藏_id字段,并且只显示title和author字段
> db.users.aggregate({"$project":{"_id":,"title":,"author":}});
{ "title" : "MongoDb Overview", "author" : "huangFeiHong" }
{ "title" : "NoSql Overview", "author" : "huangFeiHong" }
{ "title" : "Log4Net Overview", "author" : "linChong" }
{ "title" : "MongoDb Higher", "author" : "huangFeiHong" }
{ "title" : "NoSql Redis Overview", "author" : "linChong" }
{ "title" : "Memcached Overrivew", "author" : "wuSong" }
2.2、【$match】:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。$match的语法和查询表达式(db.collection.find())的语法相同
//原始数据
> db.users.find({},{_id:})
{ "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "Log4Net Overview", "description" : "log4net is not sql database", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "log", "net", "NoSQL" ], "likes" : , "quantity" : }
{ "title" : "MongoDb Higher", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "NoSql Redis Overview", "description" : "No sql database is very fast", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "redis", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "Memcached Overrivew", "description" : "Memcached is sql database", "author" : "wuSong", "url" : "http://www.wusong.com", "tags" : [ "memcached", "cache", "NoSQL" ], "likes" : , "quantity" : }
> //获取销售数量大于4并且小于等于12的作者,并按作者分组统计
> db.users.aggregate([{"$match":{"quantity":{"$gt":,"$lte":}}},{"$group":{"_id":"$author","count":{"$sum":}}}]);
{ "_id" : "wuSong", "count" : }
{ "_id" : "linChong", "count" : }
{ "_id" : "huangFeiHong", "count" : } //获取销售数量大于4并且小于等于33的作者,并按作者分组统计
> db.users.aggregate([{"$match":{"quantity":{"$gt":,"$lte":}}},{"$group":{"_id":"$author","count":{"$sum":}}}]);
{ "_id" : "wuSong", "count" : }
{ "_id" : "linChong", "count" : }
{ "_id" : "huangFeiHong", "count" : }
> //获取销售数量大于等于4并且小于等于33的作者,并按作者分组统计
> db.users.aggregate([{"$match":{"quantity":{"$gte":,"$lte":}}},{"$group":{"_id":"$author","count":{"$sum":}}}]);
{ "_id" : "wuSong", "count" : }
{ "_id" : "linChong", "count" : }
{ "_id" : "huangFeiHong", "count" : }
注意: 1、不能在$match操作符中使用$where表达式操作符。
2、$match尽量出现在管道的前面,这样可以提早过滤文档,加快聚合速度。
3、如果$match出现在最前面的话,可以使用索引来加快查询。
2.3、【$limit】:用来限制MongoDB聚合管道返回的文档数。
//原始数据
> db.users.find({},{_id:})
{ "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "Log4Net Overview", "description" : "log4net is not sql database", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "log", "net", "NoSQL" ], "likes" : , "quantity" : }
{ "title" : "MongoDb Higher", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "NoSql Redis Overview", "description" : "No sql database is very fast", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "redis", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "Memcached Overrivew", "description" : "Memcached is sql database", "author" : "wuSong", "url" : "http://www.wusong.com", "tags" : [ "memcached", "cache", "NoSQL" ], "likes" : , "quantity" : }
> //只显示前两条
> db.users.aggregate({"$limit":})
{ "_id" : ObjectId("5b1e044733091e826f7c2c74"), "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c75"), "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : } //只显示前两条,并且隐藏_id字段
> db.users.aggregate({"$limit":},{"$project":{"_id":}})
{ "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : } //只显示前四条,并且隐藏_id字段
> db.users.aggregate({"$limit":},{"$project":{"_id":}})
{ "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "Log4Net Overview", "description" : "log4net is not sql database", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "log", "net", "NoSQL" ], "likes" : , "quantity" : }
{ "title" : "MongoDb Higher", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
>
2.4、【$skip】:在聚合管道中跳过指定数量的文档,并返回余下的文档。
//原始数据
> db.users.find({},{_id:})
{ "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "Log4Net Overview", "description" : "log4net is not sql database", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "log", "net", "NoSQL" ], "likes" : , "quantity" : }
{ "title" : "MongoDb Higher", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "NoSql Redis Overview", "description" : "No sql database is very fast", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "redis", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "Memcached Overrivew", "description" : "Memcached is sql database", "author" : "wuSong", "url" : "http://www.wusong.com", "tags" : [ "memcached", "cache", "NoSQL" ], "likes" : , "quantity" : }
> //跳过前2条,从第三条记录开始显示
> db.users.aggregate({"$skip":})
{ "_id" : ObjectId("5b1e044733091e826f7c2c76"), "title" : "Log4Net Overview", "description" : "log4net is not sql database", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "log", "net", "NoSQL" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c77"), "title" : "MongoDb Higher", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c78"), "title" : "NoSql Redis Overview", "description" : "No sql database is very fast", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "redis", "database", "NoSql" ], "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c79"), "title" : "Memcached Overrivew", "description" : "Memcached is sql database", "author" : "wuSong", "url" : "http://www.wusong.com", "tags" : [ "memcached", "cache", "NoSQL" ], "likes" : , "quantity" : } //跳过前2条,从第三条记录开始显示,并结合$project 隐藏_id字段
> db.users.aggregate({"$skip":},{"$project":{"_id":}})
{ "title" : "Log4Net Overview", "description" : "log4net is not sql database", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "log", "net", "NoSQL" ], "likes" : , "quantity" : }
{ "title" : "MongoDb Higher", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "NoSql Redis Overview", "description" : "No sql database is very fast", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "redis", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "Memcached Overrivew", "description" : "Memcached is sql database", "author" : "wuSong", "url" : "http://www.wusong.com", "tags" : [ "memcached", "cache", "NoSQL" ], "likes" : , "quantity" : }
> //通过$skip和$limit分页显示,显示第一页,每页显示2条记录,并隐藏_id和url字段
> db.users.aggregate({"$skip":},{"$limit":},{"$project":{"_id":,url:}})
{ "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
> //通过$skip和$limit分页显示,显示第二页,每页显示2条记录,并隐藏_id和url字段
> db.users.aggregate({"$skip":},{"$limit":},{"$project":{"_id":,url:}})
{ "title" : "Log4Net Overview", "description" : "log4net is not sql database", "author" : "linChong", "tags" : [ "log", "net", "NoSQL" ], "likes" : , "quantity" : }
{ "title" : "MongoDb Higher", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
>
2.5、【$unwind】:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
//原始数据
> db.users.find({},{_id:})
{ "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "Log4Net Overview", "description" : "log4net is not sql database", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "log", "net", "NoSQL" ], "likes" : , "quantity" : }
{ "title" : "MongoDb Higher", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "NoSql Redis Overview", "description" : "No sql database is very fast", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "redis", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "Memcached Overrivew", "description" : "Memcached is sql database", "author" : "wuSong", "url" : "http://www.wusong.com", "tags" : [ "memcached", "cache", "NoSQL" ], "likes" : , "quantity" : }
> //把数组tags字段独立开来,每个数组元素是一条独立的记录,这是全部字段都显示的
> db.users.aggregate({"$unwind":"$tags"})
{ "_id" : ObjectId("5b1e044733091e826f7c2c74"), "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : "mongodb", "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c74"), "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : "database", "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c74"), "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : "NoSql", "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c75"), "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : "mongodb", "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c75"), "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : "database", "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c75"), "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : "NoSql", "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c76"), "title" : "Log4Net Overview", "description" : "log4net is not sql database", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : "log", "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c76"), "title" : "Log4Net Overview", "description" : "log4net is not sql database", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : "net", "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e044733091e826f7c2c76"), "title" : "Log4Net Overview", "description" : "log4net is not sql database", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : "NoSQL", "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c77"), "title" : "MongoDb Higher", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : "mongodb", "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c77"), "title" : "MongoDb Higher", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : "database", "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c77"), "title" : "MongoDb Higher", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : "NoSql", "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c78"), "title" : "NoSql Redis Overview", "description" : "No sql database is very fast", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : "redis", "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c78"), "title" : "NoSql Redis Overview", "description" : "No sql database is very fast", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : "database", "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c78"), "title" : "NoSql Redis Overview", "description" : "No sql database is very fast", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : "NoSql", "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c79"), "title" : "Memcached Overrivew", "description" : "Memcached is sql database", "author" : "wuSong", "url" : "http://www.wusong.com", "tags" : "memcached", "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c79"), "title" : "Memcached Overrivew", "description" : "Memcached is sql database", "author" : "wuSong", "url" : "http://www.wusong.com", "tags" : "cache", "likes" : , "quantity" : }
{ "_id" : ObjectId("5b1e1bfb33091e826f7c2c79"), "title" : "Memcached Overrivew", "description" : "Memcached is sql database", "author" : "wuSong", "url" : "http://www.wusong.com", "tags" : "NoSQL", "likes" : , "quantity" : }
> //把数组tags字段独立开来,每个数组元素是一条独立的记录,这里进行了字段的减少
> db.users.aggregate({"$unwind":"$tags"},{"$project":{"_id":,"url":,"description":}})
{ "title" : "MongoDb Overview", "author" : "huangFeiHong", "tags" : "mongodb", "likes" : , "quantity" : }
{ "title" : "MongoDb Overview", "author" : "huangFeiHong", "tags" : "database", "likes" : , "quantity" : }
{ "title" : "MongoDb Overview", "author" : "huangFeiHong", "tags" : "NoSql", "likes" : , "quantity" : }
{ "title" : "NoSql Overview", "author" : "huangFeiHong", "tags" : "mongodb", "likes" : , "quantity" : }
{ "title" : "NoSql Overview", "author" : "huangFeiHong", "tags" : "database", "likes" : , "quantity" : }
{ "title" : "NoSql Overview", "author" : "huangFeiHong", "tags" : "NoSql", "likes" : , "quantity" : }
{ "title" : "Log4Net Overview", "author" : "linChong", "tags" : "log", "likes" : , "quantity" : }
{ "title" : "Log4Net Overview", "author" : "linChong", "tags" : "net", "likes" : , "quantity" : }
{ "title" : "Log4Net Overview", "author" : "linChong", "tags" : "NoSQL", "likes" : , "quantity" : }
{ "title" : "MongoDb Higher", "author" : "huangFeiHong", "tags" : "mongodb", "likes" : , "quantity" : }
{ "title" : "MongoDb Higher", "author" : "huangFeiHong", "tags" : "database", "likes" : , "quantity" : }
{ "title" : "MongoDb Higher", "author" : "huangFeiHong", "tags" : "NoSql", "likes" : , "quantity" : }
{ "title" : "NoSql Redis Overview", "author" : "linChong", "tags" : "redis", "likes" : , "quantity" : }
{ "title" : "NoSql Redis Overview", "author" : "linChong", "tags" : "database", "likes" : , "quantity" : }
{ "title" : "NoSql Redis Overview", "author" : "linChong", "tags" : "NoSql", "likes" : , "quantity" : }
{ "title" : "Memcached Overrivew", "author" : "wuSong", "tags" : "memcached", "likes" : , "quantity" : }
{ "title" : "Memcached Overrivew", "author" : "wuSong", "tags" : "cache", "likes" : , "quantity" : }
{ "title" : "Memcached Overrivew", "author" : "wuSong", "tags" : "NoSQL", "likes" : , "quantity" : }
注意:1、$unwind:"$tags"})不要忘了$符号
2、如果$unwind目标字段不存在的话,那么该文档将被忽略过滤掉,例如:
> db.article.aggregate({$project:{author:1,title:1,tags:1}},{$unwind:"$tag"})
{ "result" : [ ], "ok" : 1 }
将$tags改为$tag因不存在该字段,该文档被忽略,输出的结果为空
3、如果$unwind目标字段不是一个数组的话,将会产生错误,例如:
> db.article.aggregate({$project:{author:1,title:1,tags:1}},{$unwind:"$title"})
Error: Printing Stack Trace
at printStackTrace (src/mongo/shell/utils.js:37:15)
at DBCollection.aggregate (src/mongo/shell/collection.js:897:9)
at (shell):1:12
Sat Nov 16 19:16:54.488 JavaScript execution failed: aggregate failed: {
"errmsg" : "exception: $unwind: value at end of field path must be an array",
"code" : 15978,
"ok" : 0
} at src/mongo/shell/collection.js:L898
4、如果$unwind目标字段数组为空的话,该文档也将会被忽略。
2.6、【$group】:将集合中的文档分组,可用于统计结果。
//原始数据
> db.users.find({},{_id:})
{ "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "Log4Net Overview", "description" : "log4net is not sql database", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "log", "net", "NoSQL" ], "likes" : , "quantity" : }
{ "title" : "MongoDb Higher", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "NoSql Redis Overview", "description" : "No sql database is very fast", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "redis", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "Memcached Overrivew", "description" : "Memcached is sql database", "author" : "wuSong", "url" : "http://www.wusong.com", "tags" : [ "memcached", "cache", "NoSQL" ], "likes" : , "quantity" : }
> //根据作者分类统计
> db.users.aggregate({"$group":{"_id":"$author","count":{"$sum":}}})
{ "_id" : "wuSong", "count" : }
{ "_id" : "linChong", "count" : }
{ "_id" : "huangFeiHong", "count" : } //根据作者分类统计,隐藏_id字段
> db.users.aggregate([{"$group":{"_id":"$author","count":{"$sum":}}},{"$project":{"_id":}}])
{ "count" : }
{ "count" : }
{ "count" : }
注意: 1、$group的输出是无序的。
2、$group操作目前是在内存中进行的,所以不能用它来对大量个数的文档进行分组。
2.7、【$sort】:将输入文档排序后输出。
//原始数据
> db.users.find({},{_id:})
{ "title" : "MongoDb Overview", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "NoSql Overview", "description" : "No sql database is very fast", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "Log4Net Overview", "description" : "log4net is not sql database", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "log", "net", "NoSQL" ], "likes" : , "quantity" : }
{ "title" : "MongoDb Higher", "description" : "Mongodb is not sql database", "author" : "huangFeiHong", "url" : "http://www.huangfeihong.com", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "NoSql Redis Overview", "description" : "No sql database is very fast", "author" : "linChong", "url" : "http://www.linchong.com", "tags" : [ "redis", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "Memcached Overrivew", "description" : "Memcached is sql database", "author" : "wuSong", "url" : "http://www.wusong.com", "tags" : [ "memcached", "cache", "NoSQL" ], "likes" : , "quantity" : }
> //根据quantity字段按升序排列
> db.users.aggregate([{"$sort":{"quantity":}},{"$project":{"_id":,"url":,"description":}}]);
{ "title" : "MongoDb Overview", "author" : "huangFeiHong", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "MongoDb Higher", "author" : "huangFeiHong", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "Log4Net Overview", "author" : "linChong", "tags" : [ "log", "net", "NoSQL" ], "likes" : , "quantity" : }
{ "title" : "Memcached Overrivew", "author" : "wuSong", "tags" : [ "memcached", "cache", "NoSQL" ], "likes" : , "quantity" : }
{ "title" : "NoSql Overview", "author" : "huangFeiHong", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "NoSql Redis Overview", "author" : "linChong", "tags" : [ "redis", "database", "NoSql" ], "likes" : , "quantity" : } //根据quantity字段按降序排列
> db.users.aggregate([{"$sort":{"quantity":-}},{"$project":{"_id":,"url":,"description":}}]);
{ "title" : "NoSql Redis Overview", "author" : "linChong", "tags" : [ "redis", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "NoSql Overview", "author" : "huangFeiHong", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "Memcached Overrivew", "author" : "wuSong", "tags" : [ "memcached", "cache", "NoSQL" ], "likes" : , "quantity" : }
{ "title" : "Log4Net Overview", "author" : "linChong", "tags" : [ "log", "net", "NoSQL" ], "likes" : , "quantity" : }
{ "title" : "MongoDb Overview", "author" : "huangFeiHong", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
{ "title" : "MongoDb Higher", "author" : "huangFeiHong", "tags" : [ "mongodb", "database", "NoSql" ], "likes" : , "quantity" : }
>
注意:1. 如果将$sort放到管道前面的话可以利用索引,提高效率
2. MongoDB 24.对内存做了优化,在管道中如果$sort出现在$limit之前的话,$sort只会对前$limit个文档进行操作,这样在内存中也只会保留前$limit个文档,从而可以极大的节省内存
3. $sort操作是在内存中进行的,如果其占有的内存超过物理内存的10%,程序会产生错误
2.8、【$goNear】:$goNear会返回一些坐标值,这些值以按照距离指定点距离由近到远进行排序
//原始数据
> db.geoInstance.insert([{loc:[,]},{loc:[,]},{loc:[,-]},{loc:[-,]},{loc:{x:,y:}},{loc:{lng:-9.2,lat:21.3}}])
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : ,
"nUpserted" : ,
"nMatched" : ,
"nModified" : ,
"nRemoved" : ,
"upserted" : [ ]
}) > db.geoInstance.find()
{ "_id" : ObjectId("5b1f4d21cf30d7cba03d5e03"), "loc" : [ , ] }
{ "_id" : ObjectId("5b1f4d21cf30d7cba03d5e04"), "loc" : [ , ] }
{ "_id" : ObjectId("5b1f4d21cf30d7cba03d5e05"), "loc" : [ , - ] }
{ "_id" : ObjectId("5b1f4d21cf30d7cba03d5e06"), "loc" : [ -, ] }
{ "_id" : ObjectId("5b1f4d21cf30d7cba03d5e07"), "loc" : { "x" : , "y" : } }
{ "_id" : ObjectId("5b1f4d21cf30d7cba03d5e08"), "loc" : { "lng" : -9.2, "lat" : 21.3 } }
> //注意:一定要建立2d索引,否则不能计算距离(我在这里掉坑了)
> db.geoInstance.ensureIndex({"loc":"2d"});
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : ,
"numIndexesAfter" : ,
"ok" :
} //执行结果
> db.geoInstance.aggregate({"$geoNear":{near:[,],distanceField:"distance"}})
{ "_id" : ObjectId("5b1f4d21cf30d7cba03d5e07"), "loc" : { "x" : , "y" : }, "distance" : 3.1622776601683795 }
{ "_id" : ObjectId("5b1f4d21cf30d7cba03d5e04"), "loc" : [ , ], "distance" : 7.280109889280518 }
{ "_id" : ObjectId("5b1f4d21cf30d7cba03d5e03"), "loc" : [ , ], "distance" : 9.055385138137417 }
{ "_id" : ObjectId("5b1f4d21cf30d7cba03d5e05"), "loc" : [ , - ], "distance" : 11.180339887498949 }
{ "_id" : ObjectId("5b1f4d21cf30d7cba03d5e06"), "loc" : [ -, ], "distance" : }
{ "_id" : ObjectId("5b1f4d21cf30d7cba03d5e08"), "loc" : { "lng" : -9.2, "lat" : 21.3 }, "distance" : 27.223702907576698 }
>
注意: 1、使用$goNear只能在管道处理的开始第一个阶段进行
2、必须指定distanceField,该字段用来决定是否包含距离字段
3、$gonNear和geoNear命令比较相似,但是也有一些不同:distanceField在$geoNear中是必选的,而在geoNear中是可选的;includeLocs在$geoNear中是string类型,而在geoNear中是boolen类型。
五、结束
好了,就是这些了。学习是一个渐进的过程,今天只是初步涉及“聚合”的操作,还有有差距,有些概念要好好的理解一下。不忘初心,继续努力吧。
MongoDb进阶实践之八 MongoDB的聚合初探的更多相关文章
- MongoDb进阶实践之六 MongoDB查询命令详述(补充)
一.引言 上一篇文章我们已经介绍了MongoDB数据库的查询操作,但是并没有介绍全,随着自己的学习的深入,对查询又有了新的东西,决定补充进来.如果大家想看上一篇有关MongoDB查询的 ...
- MongoDb进阶实践之三 Mongodb基本命令详解
一.引言 从今天开始,我要正式开始介绍MongoDB的使用方法了.在此之前,我用了两篇文章分别介绍了如何在Linux系统和Windows系统上安装和配置MongoDB系统.如 ...
- MongoDb进阶实践之三 MongoDB查询命令详述
一.引言 上一篇文章我们已经介绍了MongoDB数据库的最基本操作,包括数据库的创建.使用和删除数据库,文档的操作也涉及到了文档的创建.删除.更新和查询,当然也包括集合的创建.重命 ...
- MongoDb进阶实践之五 MongoDB修改命令详述
一.引言 上一篇文章我们已经详细介绍了MongoDB数据库的有关查询的内容,但是这只是所有查询命令的冰山一角.所有查询命令都写完也没有必要,我只是写了一些常用的命令,对MongoDB的 ...
- MongoDb进阶实践之七 MongoDB的索引入门
一.引言 好久没有写东西了,MongoDB系列的文章也丢下好长时间了.今天终于有时间了,就写了一篇有关索引的文章.一说到"索引",用过关系型数据库的人都应该知道它是一个什么 ...
- MongoDb进阶实践之四 MongoDB查询命令详述
一.引言 上一篇文章我们已经介绍了MongoDB数据库的最基本操作,包括数据库的创建.使用和删除数据库,文档的操作也涉及到了文档的创建.删除.更新和查询,当然也包括集合的创建.重命名和删除.有了这些基 ...
- MongoDb进阶实践之二 如何在Windows上配置MongoDB
一.引言 上一篇文章,我介绍了如何在Linux系统上安装和配置MongoDB,其实都不是很难,不需要安装和编译,省去了Make && Make Install 命 ...
- MongoDb进阶实践之一 如何在Linux(CentOS 7)上安装MongoDB
一.NoSQL数据简介 1.NoSQL概念 NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL",是 ...
- MongoDb进阶实践之一 如何在Linux系统上安装和配置MongoDB
转载来源:https://www.cnblogs.com/PatrickLiu/p/8630151.html 一.NoSQL数据简介 1.NoSQL概念 NoSQL(NoSQL = Not Only ...
随机推荐
- JAVA仿百度分页
最近在做一个仿百度网盘的网页小应用,找到了一个优雅简洁的分页插件,和百度搜索的分页很相似,对他进行了二次封装,拿出来跟大家分享下 插件源码 /** * This jQuery plugin displ ...
- Ajax 学习 第三篇
1.什么是json 第一种方法 第二种方法 比较evar and jsondata 任何时候使用EVAR要特别小心,他不会管输入对象的类型 JSONLint可以在线校验代码的正确性 改写代码
- Java解决小孩围圈问题
问题描述:一堆小孩围成一个圈,从第一个小孩开始数,每数到第三个便把第三个孩子删去,数到只剩一个小孩为止,并求该孩子的具体编号. 解决办法 1. package test; public class C ...
- 创建maven项目前的准备工作
第二步: 在maven中的settings.xml文件中指定 2.1 本地仓库:计算机中一个文件夹,自己定义是哪个文件夹. 2.1 示例语法 <localRepository>D:/mav ...
- 吴裕雄 11-MySQL查询数据
以下为在MySQL数据库中查询数据通用的 SELECT 语法:SELECT column_name,column_nameFROM table_name[WHERE Clause][LIMIT N][ ...
- 用git bash 传数据到远程出错:git push origin master 出错:error: failed to push some refs to
https://blog.csdn.net/qq_28055429/article/details/51007453
- gdufe1534-小小怪一定认真听课-dfs
Problem Description: 又到了选课的时间啦.大一萌新小小怪下士第一次选课没有制定好高效的策略,导致第一学期的学分不高,他想在第二学期获得尽可能多的学分,因此作为小小怪下士的上司搭档兼 ...
- Linux初学时的一些常用命令(4)
1. 磁盘 查看当前磁盘使用情况 df -h 查看某个文件大小 du -sh 文件名 如果不输入文件名,默认是当前目录的所有文件之和,即当前目录大小 2. 系统内存 free 参数详解:https:/ ...
- springcloud eureka.instance
1.在springcloud中服务的 Instance ID 默认值是: ${spring.cloud.client.hostname}:${spring.application.name}:${sp ...
- Java中字节流如何转字符流,OutputStreamWriter用法
OutputStreamWriter 将字节流转换为字符流.是字节流通向字符流的桥梁.如果不指定字符集编码,该解码过程将使用平台默认的字符编码,如:UTF-8: 步骤: 1.创建流 子类对象 绑定数 ...