1. 程式人生 > >mongodb 中的 map reduce 的快速入門例子,簡單操作和理解。

mongodb 中的 map reduce 的快速入門例子,簡單操作和理解。

先看下mongodb官方給出的例子的圖。

大師兄

個人理解的解釋:

這個圖,有四列資料。

第一列:原始資料。通常對應的mongodb裡面的一個表collection。

第二列:經過某些條件過濾過的資料,這個圖裡面就是按{"status":"A"}過濾資料。這個過濾的條件對應上面程式碼裡面query後面的

第三列:就是經過reduce操作之後的結果。其中的key,對應為reduce方法的引數的key,這個key來自於map函式,map函式,就是負責返回一個key value的資料結構。這個圖裡面就是以“cust_id”的值,當key,然後以“amount”欄位的值當values,注意這地方是values,不是value。這個就是這個map函式的作用,他把key去重,然後,要是相同的key對應的value就會被放到這個values裡面來,準備給reduce函式使用。

第四列:就是整個語句的執行結果啦。使用map和reduce函式,最終獲得結果。這個結果和reduce函式相關。這個圖裡面,他就是把map函式得到的key 的values求和。然後key經過去重之後,就剩下2個,然後最後的結果就產生2條資料,在mongodb裡面叫document。這2個document組成了一個新的表,mongodb管表叫collection。這個表的名字是由程式碼裡面的out欄位負責對應設定的。

經過這麼一波簡單的個人通俗的語言說明之後,就可以大致瞭解到這個mongodb的map reduce的大概作用啦。

簡單總結一下上面這個圖的意思:假設欄位cust_id程式碼使用者,amount代表金額。那麼他整體就是算符合條件(status==A)的每一個使用者的總金額是多少。

然後,根據他這個例子,咱自己也再走一個試試。具體繼續看。。。

先是mongo語句:

var map = function () {
    var key = this.region;
    var value = {
        latitude: this.latitude
    };
    emit(key, value);
};

var reduce = function (key, values) {
    var result = {
        region: key,
        totalLatitude: 0
    };
    values.forEach(function (value) {
        result.totalLatitude += value.latitude;
    });

    return result;
};

db.geos.mapReduce(
    map,
    reduce,
    {
        out: "newCollection"
    }
)

然後,我是在romongo裡面執行這個語句的。下面是執行的結果。有點長。

/* 1 */
{
    "result" : "newCollection",
    "timeMillis" : 1196.0,
    "counts" : {
        "input" : 3239,
        "emit" : 3239,
        "reduce" : 63,
        "output" : 34
    },
    "ok" : 1.0,
    "_o" : {
        "result" : "newCollection",
        "timeMillis" : 1196,
        "counts" : {
            "input" : 3239,
            "emit" : 3239,
            "reduce" : 63,
            "output" : 34
        },
        "ok" : 1.0
    },
    "_keys" : [ 
        "result", 
        "timeMillis", 
        "counts", 
        "ok"
    ],
    "_db" : {
        "_mongo" : {
            "slaveOk" : true,
            "host" : "192.168.1.161:27017",
            "defaultDB" : "ezsonar_25",
            "authStatus" : {
                "authRequired" : true,
                "isMaster" : true,
                "replSetGetStatus" : true
            },
            "_readMode" : "commands"
        },
        "_name" : "ezsonar_25"
    },
    "_coll" : {
        "_mongo" : {
            "slaveOk" : true,
            "host" : "192.168.1.161:27017",
            "defaultDB" : "ezsonar_25",
            "authStatus" : {
                "authRequired" : true,
                "isMaster" : true,
                "replSetGetStatus" : true
            },
            "_readMode" : "commands"
        },
        "_db" : {
            "_mongo" : {
                "slaveOk" : true,
                "host" : "192.168.1.161:27017",
                "defaultDB" : "ezsonar_25",
                "authStatus" : {
                    "authRequired" : true,
                    "isMaster" : true,
                    "replSetGetStatus" : true
                },
                "_readMode" : "commands"
            },
            "_name" : "ezsonar_25"
        },
        "_shortName" : "newCollection",
        "_fullName" : "ezsonar_25.newCollection"
    }
}

我使用的這個對應的model,或者叫表,或者叫collection

大師兄

然後,對我這個例子map reduce進行下解釋:

map,就是按region區域,來統計每個區域的latitude的值,這個經緯度的值。同一個region的資料document有很多,然後map函式就是把同一個region的latitude全部統計到value裡面去,我在map裡面是使用一個js物件來接受的,到時候在reduce裡面取的時候,還的以物件的形式取出來。程式碼裡面的this,就是指當前的某一個document,

reduce,就是計算一下某個region這個key對應的所有的values的經緯度的total值。

最後out到一個新的collection。資料結構具體如下:

大師兄

大師兄

生成了34條,可以看下上面的這個map reduce函式的執行結果裡面也是有這個34的

 

我寫完文章,給自己點個贊,不過分吧,
不過分,那我可就點啦啊。
我先點為敬,你們隨意。大家隨意。不要客氣。。。