你好,请问一下,我的EXCEL编辑中不能点键复制了,总是出现一个小窗口,如何取消呢?谢谢!
657
2022-05-29
聚合操作
MongoDB的聚合操作是通过数据处理管道(pipeline)来实现的,一次操作可以通过多个管道来处理,且管道是有顺序的
聚合操作可用于实现分组, 排序, 数值运算, 条件筛选,多表关联查询等
聚合管道包含非常丰富的聚合阶段,下面是最常用的聚合阶段
阶段
描述
$group
分组
$project
显示字段
$match
筛选条件
$sort/$skip/$limit
排序分页
$lookup
多表关联
$unwind
展开数组
$out
结果汇入新表
$count
文档计数
$project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。 $match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。 $limit:用来限制MongoDB聚合管道返回的文档数。 $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。 $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。 $group:将集合中的文档分组,可用于统计结果。 $sort:将输入文档排序后输出。 $geoNear:输出接近某一地理位置的有序文档
语法格式
db.collection.aggregate([ {pipeline_1}, {pipeline_2} …. ])
1 聚合-$group
$group 聚合操作符主要作用是对文档中特定字段进行分组,搭配下面的操作符对结果进行计算
操作符
说明
$sum
利用$group分组后,对同组的文档进行 计算总和
$avg
利用$group分组后,对同组的文档进行 计算平均值
$min
利用$group分组后,对同组的文档进行 获取集合中所有文档对应值得最小值。
$max
利用$group分组后,对同组的文档进行 获取集合中所有文档对应值得最大值。
$push
利用$group分组后,对同组的文档进行 以数组的方式显示指定的字段
$addToSet
将值加入一个数组中,会判断是否有重复的值,以数组的方式显示字段不重复的值
$first
根据资源文档的排序获取第一个文档数据。
$last
根据资源文档的排序获取最后一个文档数据
db.sales.drop() db.sales.insertMany([ { "_id" : 1, "item" : "abc", "price" : NumberDecimal("10"), "quantity" : NumberInt("2"), "date" : ISODate("2014-03-01T08:00:00Z") }, { "_id" : 2, "item" : "jkl", "price" : NumberDecimal("20"), "quantity" : NumberInt("1"), "date" : ISODate("2014-03-01T09:00:00Z") }, { "_id" : 3, "item" : "xyz", "price" : NumberDecimal("5"), "quantity" : NumberInt( "10"), "date" : ISODate("2014-03-15T09:00:00Z") }, { "_id" : 4, "item" : "xyz", "price" : NumberDecimal("5"), "quantity" : NumberInt("20") , "date" : ISODate("2014-04-04T11:21:39.736Z") }, { "_id" : 5, "item" : "abc", "price" : NumberDecimal("10"), "quantity" : NumberInt("10") , "date" : ISODate("2014-04-04T21:23:13.331Z") }, { "_id" : 6, "item" : "def", "price" : NumberDecimal("7.5"), "quantity": NumberInt("5" ) , "date" : ISODate("2015-06-04T05:08:13Z") }, { "_id" : 7, "item" : "def", "price" : NumberDecimal("7.5"), "quantity": NumberInt("10") , "date" : ISODate("2015-09-10T08:43:00Z") }, { "_id" : 8, "item" : "abc", "price" : NumberDecimal("10"), "quantity" : NumberInt("5" ) , "date" : ISODate("2016-02-06T20:20:13Z") }, ]) db.sales.find()
语法格式
>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION) db.collection.aggregate( [{ $group: {"_id": "$<分组字段名称>",<显示结果的名称>:{<操作符>: "$<计算的字段>"}} } ]) # select item, count( quantity ) from sales group by item db.sales.aggregate( [{$group:{"_id" : "$item", "sum":{$sum :"$quantity"} } } ]) db.sales.aggregate([{$group: {"_id": null, "count":{$sum: 1}}}]) //8 db.sales.find().size()
2 显示字段 $project
文档字段较多, 只想查询几个字段, 将预显示的字段设定为 “1”; 其余字段默认不显示(也可以设置为”0”), “_id” 较为特别, 默认显示
# 常规显示操作 db.sales.aggregate({"$project": {"_id":0, "item":1}}) # 搭配其他操作符 语法 db.collection.aggrate([ { $project: { <显示结果的名称1>:{<操作符1> : <操作符条件2>}。 <显示结果的名称2>:{<操作符2>:<操作符条件2>} } } ]) # $substr 需要三个参数:字符串, 起始参数(0 代表第一个字符), 长度参数(如为负表示截取到结尾) db.sales.aggregate({"$project": {"_id":0, "item_xxxx": {$substr: ["$item", 0,1]}}}) # $switch 对指定字段进行一系列条件判断,符合则返回 db.sales.aggregate({[{"$project": {"priceSwitch": {$switch: {branches: [ {case: {$gt: ["$price", 5], then: "price>5"}}, {case: {$lt: ["$price", 10], then: "price<10"}}], default:"price <=5 & price >=10"}} } }])
3 数据排序/跳过限制文档数量 $sort $skip $limit
需要对报表进行分页, 将”$sort” “skip” “$limit” 一起使用
操作符
说明
$sort
升序 1 降序 -1
$skip
显示文档时 跳过只读数量的文档
$limit
限制显示的文档数量
/* SELECT date, Sum(( price * quantity )) AS totalSaleAmount, Avg(quantity) AS averageQuantity, Count(*) AS Count FROM sales GROUP BY Date(date) ORDER BY totalSaleAmount DESC */ db.sales.aggregate([ // First Stage { $match : { "date": { $gte: new ISODate("2014-01-01"), $lt: new ISODate("2015-01-01") } } }, // Second Stage { $group : { _id : { $dateToString: { format: "%Y-%m-%d", date: "$date" } }, totalSaleAmount: { $sum: { $multiply: [ "$price", "$quantity" ] } }, averageQuantity: { $avg: "$quantity" }, count: { $sum: 1 } } }, // Third Stage { $sort : { totalSaleAmount: -1 } } ])
5 多表关联查询 $lookup
找出集合中与另一个集合条件匹配的文档, 类似关系型数据库的join
From 需要关联另一个集合, localField: 集合中需关联的键, foreignField 与另一个集合关联的键 As 关联后另外一个集合的数据嵌入至此字段下 db.orders.drop() db.orders.insert([ { "_id" : 1, "item" : "almonds", "price" : 12, "quantity" : 2 }, { "_id" : 2, "item" : "pecans", "price" : 20, "quantity" : 1 }, { "_id" : 3 } ]) // $lookup,多表关联 /* SELECT *, inventory_docs FROM orders WHERE inventory_docs IN ( SELECT * FROM inventory WHERE sku= orders.item ); */ db.orders.aggregate([ { $lookup: { from: "inventory", localField: "item", foreignField: "sku", as: "inventory_docs" } } ])
6 计算文档数量 $count
db.inventory.aggregate([{$match:{"qty":{$gte:50}}},{$count: "qty_count"}])
7 展开数组 $unwind
将文档中数组形式的数据拆分成数个文档,如指定字段不存在,则不会进行拆分
语法 db.collecton.aggregate([ {$unwind: {path:
db.inventory.aggregate( [ { $unwind: { path: "$tags", preserveNullAndEmptyArrays: true } }, { $group: { _id: "$tags", averageQty: { $avg: "$qty" } } }, { $sort: { "averageQty": -1 } }, { $skip: 2}, { $limit: 2} ] )
8 $out
将聚合出来的结果写入一个指定的集合中,如果原集合中有索引,写入的文档违反索引,则写入失败
// $out,将聚合结果汇入新表 db.inventory.aggregate( [ // First Stage { $unwind: { path: "$tags", preserveNullAndEmptyArrays: true } }, // Second Stage { $group: { _id: "$tags", averageQty: { $avg: "$qty" } } }, // Third Stage { $sort: { "averageQty": -1 } }, { $out : "tagsAvgQty" } ] ) db.tagsAvgQty.find();
MapReduce
MapReduce操作具有两个阶段:处理每个文档并向每个输入文档发射一个或多个对象的map阶 段,以及reduce组合map操作的输出的阶段。
Map 通过键值对形式 将相同 key 的文档 保存到 value 数组中,把结果集key value输出给 reduce阶段
Reduce 根据 key 对value 进行计算,然后再输出
语法 db.collection.mapreduce(
db.inventory.find().size() db.inventory.find() // 示例 var mapFun = function() { // 类似hashmap的put方法,不一样的地方在于同一个Key不是替换,而是追加 emit(this.status, this.qty); }; var reduceFun = function(keyCustId, valuesQty) { return Array.sum(valuesQty); }; db.inventory.mapReduce( mapFun, reduceFun, { out: "map_reduce_inventory" } ) db.map_reduce_inventory.find()
MongoDB 数据结构
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。