MongoDB(二)——Map Reduce(Node.js中实现实例)

Map Reduce

一种计算模型,就是将大批量的数据进行分解,再将分解的数据合并成最终需要的结果。

MapReduce不只是MongoDB独有,而是MongoDB也提供这个计算方法,像Java、PHP、Hadoop、Python中都可以使用,适合于处理数据量较大的场景,相较于group和aggtegate来说功能更强大,且更加灵活。

基本用法

>db.collection.mapReduce(
   function() {emit(key,value);},  //map 函数
   function(key,values) {return reduceFunction},   //reduce 函数
   {
      out: collection,
      query: document,
      sort: document,
      limit: number
   }
)

一个Map Reduce由三部分组成

Map函数

映射函数,必须调用内置的emit函数,参数key意为要根据key来进行分组,参数value将文档中的字段映射到分组后的数据上(即目标分组需要啥数据放啥数据),此处的this都指向文档

Reduce函数

统计函数,用于处理需要返回的结果,此处的参数keyvalues对应Map函数中的keyvalue返回值就是处理的结果

Options
  • out
    指定处理结果输出的集合,必选

  • query
    筛选条件,先查询再进行MapReduce操作。

  • sort
    发往Map函数前先给文档排序。

  • limit
    发往Map函数的文档数量上限。

在这里插入图片描述

实例——Node.js中使用Mongoose实现MapReduce

有如下图所示的articles文章表,现在需要将每个人的作品汇总到数组里并计算出文章总数输出。

在这里插入图片描述

show you code:
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/mongo'); // 连接数据库

//连接状态提示
var db_m = mongoose.connection;
db_m.on("error", function (error) {
    console.log("数据库连接失败:" + error);
});
db_m.on("open", function () {
    console.log("数据库连接成功");
});

// 定义Schema
var Schema = mongoose.Schema;

var articleSchema = new Schema({
    name: String,
    age: Number,
    article: String,
    status: String
})

//创建Model
var Article = mongoose.model('Article', articleSchema)

var map = function () { // 定义Map函数
    emit(this.name, { // 按名字分组
        name: this.name,
        articles: this.article,
        age: this.age,
        artcle_amount: 1,
    })
}
var reduce = function (key, values) { // 对应Map函数的参数
    var result = {
        "articles": [], // 存放文章
        "age": "",
        "artcle_amount": 0
    }
    values.forEach(value => {
        result.artcle_amount += value.artcle_amount;
        result.articles.push(value.articles);
        result.age = value.age
    });
    return result;
}
var options = {
    out: "hellos", // 输出的集合名为hello
    // query: { // 筛选条件
    //     status: "disabled"
    // }
}

db_m.collection("articles").mapReduce(
    map,
    reduce,
    options
).then(()=>{
    console.log("数据处理成功!");
    
    var helloSchema = new Schema({
    _id: String,
    value: Object
    })

    //创建Model
    var Hello = mongoose.model('Hello', helloSchema)


    Hello.find({}, (err, data) => {
        if (err) throw err;
        console.log(data); // 输出结果
        })
    })

结果:
/* 1 */
{
    "_id" : "dog",
    "value" : {
        "name" : "dog",
        "articles" : "一只单身狗的自我修养",
        "age" : 1.0,
        "artcle_amount" : 1.0
    }
}

/* 2 */
{
    "_id" : "john",
    "value" : {
        "articles" : [ 
            "BUG的艺术", 
            "BUG传"
        ],
        "age" : 24.0,
        "artcle_amount" : 2.0
    }
}

/* 3 */
{
    "_id" : "zander",
    "value" : {
        "articles" : [ 
            "BUG记", 
            "红error梦", 
            "代码演义", 
            "代码的弱点"
        ],
        "age" : 23.0,
        "artcle_amount" : 4.0
    }
}

总结:网上实例真的很少,尤其是在Node.js中实现,完全靠自我摸索,虽然aggrigate也可以实现类似的分组功能,但是灵活性就相差甚远了,而且MapReduce可以实现的功能也不止上述例子,它更占优势的地方在于对大数据的处理速度与灵活性上,更多应用场景还需要多多摸索和实践。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值