MongoDB - 映射减少
在 MongoDB 中,map-reduce 是一种数据处理编程模型,有助于对大型数据集执行操作并生成聚合结果。 MongoDB 提供了 mapReduce()函数来执行 map-reduce 操作。该函数有两个主要功能,即map函数和reduce函数。 map函数用于根据键值对所有数据进行分组,reduce函数用于对映射的数据执行操作。因此,数据在不同的空间中独立映射和缩减,然后在函数组合在一起,结果将保存到指定的新集合中。这个 mapReduce()函数通常只在大数据集上运行。使用 Map Reduce,您可以使用某个键对数据执行 max、avg 等聚合操作,它类似于 SQL 中的 groupBy。它独立和并行地处理数据。让我们尝试使用以下示例来理解 mapReduce():
在这个例子中,我们有五个记录,我们需要从中取出每个部分的最大标记,键是 id、sec、marks。
{"id":1, "sec":A, "marks":80}
{"id":2, "sec":A, "marks":90}
{"id":1, "sec":B, "marks":99}
{"id":1, "sec":B, "marks":95}
{"id":1, "sec":C, "marks":90}
这里我们需要找到每个部分的最大分数。因此,我们用来对文档进行分组的键是 sec 键,值是标记。里面的地图函数,我们使用EMIT(this.sec,this.marks)函数,我们将从EMIT函数返回每个记录(文件)的秒和标记。这类似于 group By MySQL。
var map = function(){emit(this.sec, this.marks)};
在迭代每个文档后,Emit函数将返回如下数据:
{“A”:[80, 90]}, {“B”:[99, 90]}, {“C”:[90] }
到目前为止,这就是 map()函数所做的。由emit函数给出的数据按sec 键分组,现在这些数据将输入到我们的reduce函数。 Reduce函数是实际发生数据聚合的地方。在我们的示例中,我们将选择每个部分的最大值,例如 A:[80, 90] = 90 (Max) B:[99, 90] = 99 (max) , C:[90] = 90(max)。
var reduce = function(sec,marks){return Array.max(marks);};
在 reduce()函数,我们已经减少了记录,现在我们将它们输出到一个新的集合中。{out :”collectionName”}
db.collectionName.mapReduce(map,reduce,{out :"collectionName"});
在上面的查询中,我们已经定义了映射,reduce。然后为了检查我们需要查看新创建的集合,我们可以使用查询 db.collectionName.find() 我们得到:
{"id":"A", value:90}
{"id":"B", value:99}
{"id":"C", value:90}
句法:
db.collectionName.mapReduce(
... map(),
...reduce(),
...query{},
...output{}
);
这里,
- map()函数:它使用emit()函数,其中它接受两个参数key 和value key。这里的关键是我们在 MySQL 中创建类似组的组。例如按年龄或名称分组,第二个参数是在其上执行聚合,如 avg(),sum() 是在其上计算的。
- reduce()函数:这是我们执行聚合函数(如 avg()、sum())的步骤。
- 查询:这里我们将通过查询来过滤结果集。
- 输出:在这里,我们将指定存储结果的集合名称。
示例 1:
在这个例子中,我们正在使用:
Database: geeksforgeeks2
Collection: employee
Documents: Six documents that contains the details of the employees
- 求按年龄分组的排名总和:
var map=function(){ emit(this.age,this.rank)};
var reduce=function(age,rank){ return Array.sum(rank);};
db.employee.mapReduce(map,reduce,{out :"resultCollection1"});
在这里,我们将计算特定年龄组内存在的排名总和。现在年龄是我们将执行分组依据的键(如在 MySQL 中),而排名将是我们将执行总和聚合的键。
- 里面 地图() 函数,即map() : 函数 map(){ emit(this.age,this.rank);};我们将编写emit(this.age,this.rank)函数。这里表示当前正在迭代的集合,第一个键是使用年龄的年龄,我们将对结果进行分组,例如让年龄 24 给出所有排名的总和或让年龄 25 给出所有排名的总和,第二个参数是聚合的排名将被执行。
- 在reduce函数内部,即reduce(): 函数 reduce(key,rank){ return Array.sum(rank); };我们将执行聚合函数。
- 现在将输出第三个参数,我们将在其中定义保存结果的集合,即{out :”resultCollection1″} 。这里,out 表示键,其值为保存结果的集合名称。
- 对按年龄分组的排名执行 avg() 聚合:
var map=function(){ emit(this.age,this.rank)};
var reduce=function(age,rank){ return Array.avg(rank);};
db.employee.mapReduce(map,reduce,{out :"resultCollection3"});
db.resultCollection3.find()
在本例中,我们将计算按年龄分组的排名的平均值。所以,
- map():函数map(){ emit(this.age, this.rank)};.这里年龄是我们将分组的关键,而排名是将执行 avg() 聚合的关键。
- reduce():函数reduce (age,rank){ return Array.avg(rank)l};
- 输出: {输出:”resultCollection3″}
何时使用 Map-Reduce?
在 MongoDB 中,当您的聚合查询很慢时,您可以使用 Map-reduce,因为数据量很大并且聚合查询需要更多时间来处理。因此,使用 map-reduce 可以比聚合查询更快地执行操作。