title: MongoDB Map-Reduce 操作文档
date: 2023-09-22 13:35:49
categories:
- mongodb
tags:
目录
1. 简介
MongoDB的Map-Reduce是一种用于数据分析和聚合的方法。它将数据映射到一组中间键值对,然后将这些中间结果按照一定规则归并,最终生成结果。
2. 准备工作
确保你已经连接到MongoDB数据库,并具有合适的权限执行Map-Reduce操作。
3. 编写Map函数
创建一个JavaScript函数,用于定义Map操作。这个函数会被应用到每个文档上,生成键值对作为中间结果。示例:
var mapFunction = function() {
// 在这里编写你的Map逻辑
emit(this.category, this.value);
};
4. 编写Reduce函数
创建另一个JavaScript函数,用于定义Reduce操作。这个函数将中间结果按键进行归并。示例:
var reduceFunction = function(key, values) {
// 在这里编写你的Reduce逻辑
return Array.sum(values);
};
5. 执行Map-Reduce
使用mapReduce方法执行Map-Reduce操作。示例:
db.yourCollection.mapReduce(
mapFunction,
reduceFunction,
{ out: "outputCollection" }
);
6. 结果获取
你可以在指定的输出集合中获取Map-Reduce的结果。
7. 示例
以下是一个完整的Map-Reduce示例:
var mapFunction = function() {
emit(this.category, this.value);
};
var reduceFunction = function(key, values) {
return Array.sum(values);
};
db.sales.mapReduce(
mapFunction,
reduceFunction,
{ out: "category_totals" }
);
8.常见的聚合函数
你可以根据需要选择合适的聚合函数来操作数据。
1. Array.sum(values)
将值数组中的所有元素相加,用于计算总和。
2. Array.avg(values)
计算值数组中元素的平均值。
3. Array.max(values)
找出值数组中的最大值。
4. Array.min(values)
找出值数组中的最小值。
5. Array.push(values)
将所有值数组中的元素放入一个新的数组中,可用于收集数据。
6. Array.concat(values)
将所有值数组中的元素连接成一个新的数组。
7. Array.join(values, separator)
将所有值数组中的元素用指定的分隔符连接成一个字符串。
自定义聚合逻辑
如果以上函数不满足你的需求,你可以编写自定义的Reduce函数,以执行更复杂的聚合操作。
示例
演示如何使用Map-Reduce来计算每个用户的平均购买价格和购买次数。
假设有一个包含购买记录的文档集合,每个文档包括以下字段:userId(用户ID)、purchaseAmount(购买金额)和purchaseDate(购买日期)。
创建语句
db.createCollection("purchases");
创建语句为:
db.createCollection("purchases");
// 插入购买记录文档
db.purchases.insertMany([
{
userId: "user1",
purchaseAmount: 50.0,
purchaseDate: ISODate("2023-09-22T08:00:00Z")
},
{
userId: "user2",
purchaseAmount: 30.5,
purchaseDate: ISODate("2023-09-22T09:15:00Z")
},
{
userId: "user1",
purchaseAmount: 25.0,
purchaseDate: ISODate("2023-09-22T10:30:00Z")
},
{
userId: "user3",
purchaseAmount: 60.2,
purchaseDate: ISODate("2023-09-22T11:45:00Z")
},
{
userId: "user2",
purchaseAmount: 15.8,
purchaseDate: ISODate("2023-09-22T14:20:00Z")
}
]);
map 函数
var mapFunction = function() {
// 以用户ID作为键,将购买金额和购买次数作为值
emit(this.userId, { totalAmount: this.purchaseAmount, count: 1 });
};
reduce 函数
var reduceFunction = function(key, values) {
var reducedValue = { totalAmount: 0, count: 0 };
// 遍历所有购买记录
for (var i = 0; i < values.length; i++) {
reducedValue.totalAmount += values[i].totalAmount;
reducedValue.count += values[i].count;
}
return reducedValue;
};
在Reduce函数中,我们遍历了具有相同用户ID的所有购买记录,将它们的购买金额和购买次数累加起来。
最后,通过这个Map-Reduce操作,你可以获得每个用户的平均购买价格,只需将总金额除以购买次数:
最终结果获取:
var finalizeFunction = function(key, reducedValue) {
reducedValue.averagePrice = reducedValue.totalAmount / reducedValue.count;
return reducedValue;
};h
db.purchases.mapReduce(
mapFunction,
reduceFunction,
{
out: "user_purchase_stats",
finalize: finalizeFunction
}
);
在这个示例中,我们还使用了 finalize 选项来计算每个用户的平均购买价格,并将其添加到最终结果中。