首页 > 编程笔记 > MySQL笔记 阅读:10

MongoDB map-reduce执行聚合操作(附带实例)

聚合操作主要用于处理数据并返回计算结果。聚合操作将来自多个文档的值组合在一起,按条件分组后,再进行一系列操作(如求和、计算平均值、计算最大值、计算最小值)以返回单个结果。

MongoDB 提供了 3 种执行聚合的操作,分别是聚合管道、map-reduce 和单一目标聚合,接下来重点介绍 map-reduce。

MongoDB 提供了 map-reduce 操作来执行聚合。map-reduce 操作通常包括两个阶段:
与其他聚合操作相同,map-reduce 操作可以指定查询条件,以选择输入文档以及排序和限制结果。

map-reduce 操作使用自定义 JavaScript 函数来执行映射和减少操作,虽然自定义 JavaScript 函数比聚合管道具有更大的灵活性,但 map-reduce 操作比聚合管道的效率更低、操作更复杂。map-reduce 操作可以在分片集合上运行,也可以把输出结果存储到分片集合中。

map-reduce 操作的语法如下:
> db.collection.mapReduce(
    function() { emit(key,value); },
    function(key, values) { return reduceFunction }{ query: document, out: collection }
)
function(){emit(key, value); } 为 map 阶段函数,负责生成键值对序列,并作为 reduce 阶段函数输入参数。

function(key, values) {return reduceFunction} 为 reduce 阶段函数,该函数的任务是将 key-values 变成 key-value,也就是把 values 数组转换成单一的值 value。query 参数设置筛选条件,只有满足条件的文档才会调用 map 阶段函数。out 参数为统计结果的存储集合,如果不指定则使用临时集合,但会在客户端断开后自动删除该临时集合。

下面举例说明使用 map-reduce 操作进行数据聚合的过程。首先插入数据,数据表示每位顾客 cust_id 的消费情况,代码如下:
db.order.insert([
{"cust_id": "1", "status": "A", "price": 25, "items": [{"sku": "mmm", "qty":5, "price": 2.5}, {"sku": "nnn", "qty": 5, "price": 2.5}]},
{"cust_id": "1", "status": "A", "price": 25, "items": [{"sku": "mmm", "qty":5, "price": 2.5}, {"sku": "nnn", "qty": 5, "price": 2.5}]},
{"cust_id": "2", "status": "A", "price": 25, "items": [{"sku": "mmm", "qty":5, "price": 2.5}, {"sku": "nnn", "qty": 5, "price": 2.5}]},
{"cust_id": "3", "status": "A", "price": 25, "items": [{"sku": "mmm", "qty":5, "price": 2.5}, {"sku": "nnn", "qty": 5, "price": 2.5}]},
{"cust_id": "3"," status": "A", "price": 30, "items": [{"sku": "mmm", "qty":6, "price": 2.5}, {"sku": "nnn", "qty": 6, "price": 2.5}]}
])

编写 map 阶段函数,将 cust_id 作为阶段函数的输出 key,price 作为阶段函数的输出 value,代码如下:
var mapFunc = function() {
    emit(this.cust_id, this.price);
};

编写 reduce 阶段函数,将相同的 map 阶段函数的输出 key 聚合起来,并对输出 ()value 进行求和(sum)操作,代码如下:
var reduceFunc = function(key, values) {
    return Array.sum(values);
};

执行 map-reduce 操作,将 reduce 阶段函数的输出结果保存在集合 map_result_result 中,代码如下:
> db.order.mapReduce(mapFunc, reduceFunc, {out: {replace: 'map_result_result'}})

查看当前数据库下的所有集合,我们会发现 MongoDB 新建了一个 map_result_result。该集合里保存了执行 map-reduce 操作后的聚合结果,具体如下:
> show collections
map_result_result
myColl
order
> db.map_result_result.find()
{"_id": "1", "value": 50.0}
{"_id": "2", "value": 25.0}
{"_id": "3", "value": 55.0}

相关文章