今天看啥
热点:

MongoDB数据库数据聚合&管道操作,mongodb数据库聚合


管道操作

mongodb 的数据聚合过程通常会配合管道操作,mongodb 的管道操作概念类似于 LInux 中的管道概念,mongodb 的聚合管道将 mongodb 文档在一个管道处理完毕后将结果传递给下一个管道处理,管道操作是可以以此重复的;
mongodb 管道使用 aggregte() 方法,使用管道表达式表示一个管道过程,表达式是无状态的,只能计算当前聚合管道的文档,不能处理其他文档,以下是常用的几种管道操作表达式:
聚合操作使用 aggregate() 函数,该函数原型为:db.collection_name.aggregate()
其中 opeation 参数常用的表达式:
表达式 说明
$project 修改输入文档的结构,可以用于重命名、增加/删除域、创建计算结果、嵌套文档;
$match 用于过滤数据,只输出符合条件的文档,$match 使用MongoDB的标准查询操作;
$limit 用来限制MongoDB聚合管道返回的文档数;
$skip 在聚合管道中跳过指定数量的文档,并返回余下的文档;
$count 显示当前管道的文档数量
$size 显示一个键(该键为数组类型)的数组长度;
$unwind 将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值;
$group 将集合中的文档分组,可用于统计结果;
$sort 将输入文档排序后输出;
$geoNear 输出接近某一地理位置的有序文档;


关于管道完整表达式列表的用法,参见:https://docs.mongodb.com/manual/reference/operator/aggregation-pipeline/
示例使用:以下为示例使用集合 blog 的文档结构:
?
{
 ? _id: ObjectId("5a88f21ac05302a3b998abb9"),
 ? title: 'MongoDB Overview', 
 ? description: 'MongoDB is no sql database',
 ? author: 'assad',
 ? url: 'https://blog.assad.artcile/1',
 ? tags: ['mongodb', 'database', 'NoSQL'],
 ? likes: 100
},
{
 ? _id: ObjectId("5a88f278c05302a3b998abba"),
 ? title: 'NoSQL Overview', 
 ? description: 'No sql database is very fast',
 ? author: 'Tim',
 ? url: 'https://blog.assad.artcile/34',
 ? tags: ['mongodb', 'database', 'NoSQL'],
 ? likes: 233
},
{
 ? _id: ObjectId("5a88f299c05302a3b998abbb"),
 ? title: 'SqlLite Overview', 
 ? description: 'SqlLite is no sql database',
 ? author: 'assad',
 ? url: 'https://blog.assad.artcile/213',
 ? tags: ['SqlLite', 'database', 'NoSQL'],
 ? likes: 666
}

示例:?
# $project 示例:只显示 blog 集合的 title,author,likes 字段
 > db.blog.aggregate( 
 ... ? ? [ {$project:{_id:0,title:1,author:1,likes:1}} ] 
 ... )
?
{ "author" : "assad", "likes" : 100, "title" : "article_title" }
{ "author" : "Tim", "likes" : 233, "title" : "article_title" }
{ "author" : "assad", "likes" : 666, "title" : "article_title" }
?
# $count 示例:显示 blog 集合中 likes>100, likes<500 的文档的数量
> db.blog.aggregate([
... { $match:{likes:{$gt:100,$lt:500}} },
... { $count:"result" }
... ])
{ "result" : 1 }
?
# 综合示例:显示 blog 集合中每一条文档的 tages 总数
> db.blog.aggregate([
... ?  { $project:{_id:0,title:1,tages_count:{$size:"$tags"}} } 
...])
?
{ "title" : "MongoDB Overview", "tages_count" : 3 }
{ "title" : "NoSQL Overview", "tages_count" : 3 }
{ "title" : "SqlLite Overview", "tages_count" : 3 }
?
# 综合示例:显示 blog 集合中 author="assad", likes>=100, likes<=800 的文档,按 likes 正序排序,只显示前 5 个文档,只显示 title,author,likes 字段
> db.blog.aggregate( [
...  { $project:{title:1,author:1,likes:1} },
...  { $match:{author:"assad",likes:{$gte:100,$lte:800}} },
...  { $limit:5 },
...  { $sort:{likes:1} }
... ]}
?
{ "_id" : ObjectId("5a88f21ac05302a3b998abb9"), "title" : "MongoDB Overview", "author" : "assad", "likes" : 100 }
{ "_id" : ObjectId("5a88f299c05302a3b998abbb"), "title" : "SqlLite Overview", "author" : "assad", "likes" : 666 }
?
# 综合示例:显示 blog 集合中 tags 键数组中各个值出现次数的统计
> db.blog.aggregate([
... ?  { $unwind:"$tags" }, 
... ?  { $group:{_id:"$tags",count:{$sum:1}}} 
... ])
?
{ "_id" : "SqlLite", "count" : 1 }
{ "_id" : "NoSQL", "count" : 3 }
{ "_id" : "database", "count" : 3 }
{ "_id" : "mongodb", "count" : 2 }


$group 分组表达式

在 aggregate() 方法中使用 $group 表达式进行分组操作,类似于 SQL 中的 group by 子句,$group 常用的聚合表达式如下:
表达式 说明
$sum 计算总和;
$avg 计算平均值;
$max 获取文档对应键值的最大值上限;
$min 获取文档对应键值的最小值;
$first 根据文档的排序获取第一个文档;
$last 根据文档的排序获取最后一个文档;
$push 在结果文档中插入一个数组;
$addToSet 在结果文档中插入一个数组,但是不创建副本;

示例:演示 $sum?
# 显示每一个 author 各自的 likes 总数
> db.blog.aggregate(
... ?  [ {$group:{_id:"$author",likes_count:{$sum:"$likes"} }} ]
...)
?
{ "_id" : "Tim", "likes_count" : 233 }
{ "_id" : "assad", "likes_count" : 766 }
?
# 显示所有文档的 likes 总数
> db.blog.aggregate(
... ?  [ {$group:{_id:null, likes_count:{$sum:"$likes"} }} ]
...)
?
{ "_id" : null, "likes_count" : 999 }
演示 $avg
?
# 显示各个 author 的 likes 平均数
> db.blog.aggregate(
... ?  [ {$group:{_id:"$author",likes_avg:{$avg:"$likes"} }} ]
...)
?
{ "_id" : "Tim", "likes_avg" : 233 }
{ "_id" : "assad", "likes_avg" : 383 }
?
# 显示所有文档 likes 的平均数
> db.blog.aggregate(
... ?  [ {$group:{_id:null, likes_avg:{$avg:"$likes"} }} ]
...)
?
{ "_id" : null, "likes_avg" : 333 }
?
演示 $min,$max
?
# 显示每一个 author 的 likes 最小值记录
> db.blog.aggregate(
... ? ? [ {$group:{_id:"$author",likes_min:{$min:"$likes"} }} ]
... )
?
{ "_id" : "Tim", "likes_min" : 233 }
{ "_id" : "assad", "likes_min" : 100 }
?
# 显示所有文档记录中 likes 最小的记录
> db.blog.aggregate(
... ? ? [ {$group:{_id:null, likes_min:{$min:"$likes"} }} ]
... )
?
{ "_id" : null, "likes_min" : 100 }
?
# 显示所有文档记录中 likes 最大的记录
> db.blog.aggregate(
... ? ? [ {$group:{_id:null, likes_max:{$max:"$likes"} }} ]
... )
?
{ "_id" : null, "likes_max" : 666 }
演示?$push
?
# 显示各个 author 的 article title 和 likes 列表
> db.blog.aggregate(
... ? ? [ {$group:{_id:"$author",article_like:{$push:{title:"$title",likes:"$likes"}}}} ]
... )
?
{ "_id" : "Tim", "article_like" : [ { "title" : "NoSQL Overview", "likes" : 233 } ] }
{ "_id" : "assad", "article_like" : [ { "title" : "MongoDB Overview", "likes" : 100 }, { "article" : "SqlLite Overview", "likes" : 666 } ] }


按时间分组聚合对于时间,按年月日,小时分钟秒进行分组聚合,可以使用以下表达式获取时间参数:$dayOfYear: 返回该日期是这一年的第几天(全年 366 天)。
$dayOfMonth: 返回该日期是这一个月的第几天(1到31)。
$dayOfWeek: 返回的是这个周的星期几(1:星期日,7:星期六)。
$year: 返回该日期的年份部分。
$month: 返回该日期的月份部分( 1 到 12)。
$week: 返回该日期是所在年的第几个星期( 0 到 53)。
$hour: 返回该日期的小时部分。
$minute: 返回该日期的分钟部分。
$second: 返回该日期的秒部分(以0到59之间的数字形式返回日期的第二部分,但可以是60来计算闰秒)。
$millisecond:返回该日期的毫秒部分( 0 到 999)。
$dateToString: { $dateToString: { format: , date: } }。
以下是示例用的 loginLog 集合内容:
?
{
 ? ? ? ?"_id" : ObjectId("5a8969f54a7c036151cce245"),
 ? ? ? ?"ip" : "25.12.4.42",
 ? ? ? ?"date" : ISODate("2018-02-16T09:33:12Z")
}
{
 ? ? ? ?"_id" : ObjectId("5a896a164a7c036151cce246"),
 ? ? ? ?"ip" : "126:123:11:1",
 ? ? ? ?"date" : ISODate("2018-02-17T10:20:00Z")
}
{
 ? ? ? ?"_id" : ObjectId("5a896a2c4a7c036151cce247"),
 ? ? ? ?"ip" : "23.88.44.22",
 ? ? ? ?"date" : ISODate("2018-01-20T20:30:00Z")
}
{
 ? ? ? ?"_id" : ObjectId("5a896a4a4a7c036151cce248"),
 ? ? ? ?"ip" : "55.78.22.123",
 ? ? ? ?"date" : ISODate("2018-02-19T21:59:20Z")
}
>
示例:
?
# 统计每个月分组的文档总数
> db.loginLog.aggregate([
... ? ? { $group:{_id:{$month:"$date"},log_count:{$sum:1}} }
... ])
?
{ "_id" : 1, "log_count" : 1 }
{ "_id" : 2, "log_count" : 3 }

www.bkjia.comtruehttp://www.bkjia.com/DB2/1305641.htmlTechArticleMongoDB数据库数据聚合amp;管道操作,mongodb数据库聚合 管道操作 mongodb 的数据聚合过程通常会配合管道操作,mongodb 的管道操作概念类似于...

相关文章

帮客评论

视觉看点