国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

MongoDB指南---17、MapReduce

jonh_felix / 3103人閱讀

摘要:操作花費的時間,單位是毫秒。處理完成后,會自動將臨時集合的名字更改為你指定的集合名,這個重命名的過程是原子性的。作用域在這些函數(shù)內(nèi)部是不變的。上一篇文章指南聚合下一篇文章指南聚合命令

上一篇文章:MongoDB指南---16、聚合
下一篇文章:MongoDB指南---18、聚合命令

MapReduce是聚合工具中的明星,它非常強大、非常靈活。有些問題過于復(fù)雜,無法使用聚合框架的查詢語言來表達,這時可以使用MapReduce。MapReduce使用JavaScript作為“查詢語言”,因此它能夠表達任意復(fù)雜的邏輯。然而,這種強大是有代價的:MapReduce非常慢,不應(yīng)該用在實時的數(shù)據(jù)分析中。
MapReduce能夠在多臺服務(wù)器之間并行執(zhí)行。它會將一個大問題分割為多個小問題,將各個小問題發(fā)送到不同的機器上,每臺機器只負責(zé)完成一部分工作。所有機器都完成時,再將這些零碎的解決方案合并為一個完整的解決方案。
MapReduce需要幾個步驟。最開始是映射(map),將操作映射到集合中的每個文檔。這個操作要么“無作為”,要么“產(chǎn)生一些鍵和X個值”。然后就是中間環(huán)節(jié),稱作洗牌(shuffle),按照鍵分組,并將產(chǎn)生的鍵值組成列表放到對應(yīng)的鍵中。化簡(reduce)則把列表中的值化簡成一個單值。這個值被返回,然后接著進行洗牌,直到每個鍵的列表只有一個值為止,這個值也就是最終結(jié)果。
下面會多舉幾個MapReduce的例子,這個工具非常強大,但也有點復(fù)雜。

 示例1:找出集合中的所有鍵

用MapReduce來解決這個問題有點大材小用,不過還是一種了解其機制的不錯的方式。要是已經(jīng)知道MapReduce的原理,則直接跳到本節(jié)最后,看看MongoDB中MapReduce的使用注意事項。
MongoDB會假設(shè)你的模式是動態(tài)的,所以并不跟蹤記錄每個文檔中的鍵。通常找到集合中所有文檔所有鍵的最好方式就是用MapReduce。在本例中,會記錄每個鍵出現(xiàn)了多少次。內(nèi)嵌文檔中的鍵就不計算了,但給map函數(shù)做個簡單修改就能實現(xiàn)這個功能了。
在映射環(huán)節(jié),我們希望得到集合中每個文檔的所有鍵。map函數(shù)使用特別的emit函數(shù)“返回”要處理的值。emit會給MapReduce一個鍵(類似于前面$group所使用的鍵)和一個值。這里用emit將文檔某個鍵的計數(shù)(count)返回({count : 1})。我們想為每個鍵多帶帶計數(shù),所以為文檔中的每個鍵調(diào)用一次emit。this就是當(dāng)前映射文檔的引用:

> map = function() {
... for (var key in this) {
...     emit(key, {count : 1});
... }};

這樣就有了許許多多{count : 1}文檔,每一個都與集合中的一個鍵相關(guān)。這種由一個或多個{count : 1}文檔組成的數(shù)組,會傳遞給reduce函數(shù)。reduce函數(shù)有兩個參數(shù),一個是key,也就是emit返回的第一個值,還有另外一個數(shù)組,由一個或者多個與鍵對應(yīng)的{count : 1}文檔組成。

> reduce = function(key, emits) {
... total = 0;
... for (var i in emits) {
...     total += emits[i].count;
... }
... return {"count" : total};
... }

reduce一定要能夠在之前的map階段或者前一個reduce階段的結(jié)果上反復(fù)執(zhí)行。所以reduce返回的文檔必須能作為reduce的第二個參數(shù)的一個元素。例如,x鍵映射到了3個文檔{count : 1,id : 1}、{count : 1,id : 2}和{count : 1,id : 3},其中id鍵只用于區(qū)分不同的文檔。MongoDB可能會這樣調(diào)用reduce:

> r1 = reduce("x", [{count : 1, id : 1}, {count : 1, id : 2}])
{count : 2}
> r2 = reduce("x", [{count : 1, id : 3}])
{count : 1}
> reduce("x", [r1, r2])
{count : 3}

不能認(rèn)為第二個參數(shù)總是初始文檔之一(比如{count:1})或者長度固定。reduce應(yīng)該能處理emit文檔和其他reduce返回結(jié)果的各種組合。
總之,MapReduce函數(shù)可能會是下面這樣:

> mr = db.runCommand({"mapreduce" : "foo", "map" : map, "reduce" : reduce})
{
    "result" : "tmp.mr.mapreduce_1266787811_1",
    "timeMillis" : 12,
    "counts" : {
        "input" : 6
        "emit" : 14
        "output" : 5
    },
    "ok" : true
}

MapReduce返回的文檔包含很多與操作有關(guān)的元信息。

"result" : "tmp.mr.mapreduce_1266787811_1"

這是存放MapReduce結(jié)果的集合名。這是個臨時集合,MapReduce的連接關(guān)閉后它就被自動刪除了。本章稍后會介紹如何指定一個好一點的名字以及將結(jié)果集合持久化。

"timeMillis" : 12

操作花費的時間,單位是毫秒。

"counts" : { ... }

這個內(nèi)嵌文檔主要用作調(diào)試,其中包含3個鍵。

"input" : 6

發(fā)送到map函數(shù)的文檔個數(shù)。

"emit" : 14

在map函數(shù)中emit被調(diào)用的次數(shù)。

"output" : 5

結(jié)果集合中的文檔數(shù)量。
對結(jié)果集合進行查詢會發(fā)現(xiàn)原有集合的所有鍵及其計數(shù):
···

db[mr.result].find()
{ "_id" : "_id", "value" : { "count" : 6 } }
{ "_id" : "a", "value" : { "count" : 4 } }
{ "_id" : "b", "value" : { "count" : 2 } }
{ "_id" : "x", "value" : { "count" : 1 } }
{ "_id" : "y", "value" : { "count" : 1 } }
···
這個結(jié)果集中的每個"_id"對應(yīng)原集合中的一個鍵,"value"鍵的值就是reduce的最終結(jié)果。
 示例2:網(wǎng)頁分類

假設(shè)有個網(wǎng)站,人們可以提交其他網(wǎng)頁的鏈接,比如reddit(http://www.reddit.com)。提交者可以給這個鏈接添加標(biāo)簽,表明主題,比如politics、geek或者icanhascheezburger。可以用MapReduce找出哪個主題最為熱門,熱門與否由最近的投票決定。
首先,建立一個map函數(shù),發(fā)出(emit)標(biāo)簽和一個基于流行度和新舊程度的值。

map = function() {
    for (var i in this.tags) {
        var recency = 1/(new Date() - this.date); 
        var score = recency * this.score;

        emit(this.tags[i], {"urls" : [this.url], "score" : score});
    }
};

現(xiàn)在就化簡同一個標(biāo)簽的所有值,以得到這個標(biāo)簽的分?jǐn)?shù):

reduce = function(key, emits) {
    var total = {urls : [], score : 0}
    for (var i in emits) {
        emits[i].urls.forEach(function(url) {
            total.urls.push(url);
        }
        total.score += emits[i].score;
    }
    return total;
};

最終的集合包含每個標(biāo)簽的URL列表和表示該標(biāo)簽流行程度的分?jǐn)?shù)。

 MongoDB和MapReduce

前面兩個例子只用到了mapreduce、map和reduce鍵。這3個鍵是必需的,但是MapReduce命令還有很多可選的鍵。

"finalize" : function

可以將reduce的結(jié)果發(fā)送給這個鍵,這是整個處理過程的最后一步。

"keeptemp" : boolean

如果為值為true,那么在連接關(guān)閉時會將臨時結(jié)果集合保存下來,否則不保存。

"out" : string

輸出集合的名稱。如果設(shè)置了這選項,系統(tǒng)會自動設(shè)置keeptemp : true。

"query" : document

在發(fā)往map函數(shù)前,先用指定條件過濾文檔。

"sort" : document

在發(fā)往map前先給文檔排序(與limit一同使用非常有用)。

"limit" : integer

發(fā)往map函數(shù)的文檔數(shù)量的上限。

"scope" : document

可以在JavaScript代碼中使用的變量。

"verbose" : boolean

是否記錄詳細的服務(wù)器日志。

1. finalize函數(shù)

和group命令一樣,MapReduce也可以使用finalize函數(shù)作為參數(shù)。它會在最后一個reduce輸出結(jié)果后執(zhí)行,然后將結(jié)果存到臨時集合中。
返回體積比較大的結(jié)果集對MapReduce不是什么大不了的事情,因為它不像group那樣有4 MB的限制。然而,信息總是要傳遞出去的,通常來說,finalize是計算平均數(shù)、裁剪數(shù)組、清除多余信息的好時機。

2. 保存結(jié)果集合

默認(rèn)情況下,Mongo會在執(zhí)行MapReduce時創(chuàng)建一個臨時集合,集合名是系統(tǒng)選的一個不太常用的名字,將"mr"、執(zhí)行MapReduce的集合名、時間戳以及數(shù)據(jù)庫作業(yè)ID,用“.”連成一個字符串,這就是臨時集合的名字。結(jié)果產(chǎn)生形如mr.stuff.18234210220.2這樣的名字。MongoDB會在調(diào)用的連接關(guān)閉時自動銷毀這個集合(也可以在用完之后手動刪除)。如果希望保存這個集合,就要將keeptemp選項指定為true。
如果要經(jīng)常使用這個臨時集合,你可能想給它起個好點的名字。利用out選項(該選項接受字符串作為參數(shù))就可以為臨時集合指定一個易讀易懂的名字。如果用了out選項,就不必指定keeptemp : true了,因為指定out選項時系統(tǒng)會將keeptemp設(shè)置為true。即便你取了一個非常好的名字,MongoDB也會在MapReduce的中間過程使用自動生成的集合名。處理完成后,會自動將臨時集合的名字更改為你指定的集合名,這個重命名的過程是原子性的。也就是說,如果多次對同一個集合調(diào)用MapReduce,也不會在操作中遇到集合不完整的情況。
MapReduce產(chǎn)生的集合就是一個普通的集合,在這個集合上執(zhí)行MapReduce完全沒有問題,或者在前一個MapReduce的結(jié)果上執(zhí)行MapReduce也沒有問題,如此往復(fù)直到無窮都沒問題!

3. 對文檔子集執(zhí)行MapReduce

有時需要對集合的一部分執(zhí)行MapReduce。只需在傳給map函數(shù)前使用查詢對文檔進行過濾就好了。
每個傳遞給map函數(shù)的文檔都要先反序列化,從BSON對象轉(zhuǎn)換為JavaScript對象,這個過程非常耗時。如果事先知道只需要對集合的一部分文檔執(zhí)行MapReduce,那么在map之前先對文檔進行過濾可以極大地提高map速度。可以通過"query"、"limit"和"sort"等鍵對文檔進行過濾。
"query"鍵的值是一個查詢文檔。通常查詢返回的結(jié)果會傳遞給map函數(shù)。例如,有一個做跟蹤分析的應(yīng)用程序,現(xiàn)在我們需要上周的總結(jié)摘要,只要使用如下命令對上周的文檔執(zhí)行MapReduce就好了:

> db.runCommand({"mapreduce" : "analytics", "map" : map, "reduce" : reduce,
                 "query" : {"date" : {"$gt" : week_ago}}})

sort選項和limit一起使用時通常能夠發(fā)揮非常大的作用。limit也可以多帶帶使用,用來截取一部分文檔發(fā)送給map函數(shù)。
如果在上個例子中想分析最近10 000個頁面的訪問次數(shù)(而不是最近一周的),就可以使用limit和sort:

> db.runCommand({"mapreduce" : "analytics", "map" : map, "reduce" : reduce,
                 "limit" : 10000, "sort" : {"date" : -1}})

query、limit、sort可以隨意組合,但是如果不使用limit的話,sort就不能有效發(fā)揮作用。

4. 使用作用域

MapReduce可以為map、reduce、finalize函數(shù)都采用一種代碼類型。但多數(shù)語言里,可以指定傳遞代碼的作用域。然而MapReduce會忽略這個作用域。它有自己的作用域鍵"scope",如果想在MapReduce中使用客戶端的值,則必須使用這個參數(shù)。可以用“變量名 : 值”這樣的普通文檔來設(shè)置該選項,然后在map、reduce和finalize函數(shù)中就能使用了。作用域在這些函數(shù)內(nèi)部是不變的。例如,上一節(jié)的例子使用1/(newDate() - this.date)計算頁面的新舊程度。可以將當(dāng)前日期作為作用域的一部分傳遞進去:

> db.runCommand({"mapreduce" : "webpages", "map" : map, "reduce" : reduce,
                 "scope" : {now : new Date()}})

這樣,在map函數(shù)中就能計算1/(now - this.date)了。

5. 獲得更多的輸出

還有個用于調(diào)試的詳細輸出選項。如果想看看MapReduce的運行過程,可以將"verbose"指定為true。
也可以用print把map、reduce、finalize過程中的信息輸出到服務(wù)器日志上。

上一篇文章:MongoDB指南---16、聚合
下一篇文章:MongoDB指南---18、聚合命令

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/19573.html

相關(guān)文章

  • MongoDB指南---17MapReduce

    摘要:操作花費的時間,單位是毫秒。處理完成后,會自動將臨時集合的名字更改為你指定的集合名,這個重命名的過程是原子性的。作用域在這些函數(shù)內(nèi)部是不變的。上一篇文章指南聚合下一篇文章指南聚合命令 上一篇文章:MongoDB指南---16、聚合下一篇文章:MongoDB指南---18、聚合命令 MapReduce是聚合工具中的明星,它非常強大、非常靈活。有些問題過于復(fù)雜,無法使用聚合框架的查詢語言...

    pubdreamcc 評論0 收藏0
  • MongoDB指南---16、聚合

    摘要:將返回結(jié)果限制為前個。所以,聚合的結(jié)果必須要限制在以內(nèi)支持的最大響應(yīng)消息大小。包含字段和排除字段的規(guī)則與常規(guī)查詢中的語法一致。改變字符大小寫的操作,只保證對羅馬字符有效。只對羅馬字符組成的字符串有效。 上一篇文章:MongoDB指南---15、特殊的索引和集合:地理空間索引、使用GridFS存儲文件下一篇文章:MongoDB指南---17、MapReduce 如果你有數(shù)據(jù)存儲在Mon...

    Keagan 評論0 收藏0
  • MongoDB指南---16、聚合

    摘要:將返回結(jié)果限制為前個。所以,聚合的結(jié)果必須要限制在以內(nèi)支持的最大響應(yīng)消息大小。包含字段和排除字段的規(guī)則與常規(guī)查詢中的語法一致。改變字符大小寫的操作,只保證對羅馬字符有效。只對羅馬字符組成的字符串有效。 上一篇文章:MongoDB指南---15、特殊的索引和集合:地理空間索引、使用GridFS存儲文件下一篇文章:MongoDB指南---17、MapReduce 如果你有數(shù)據(jù)存儲在Mon...

    _Zhao 評論0 收藏0
  • MongoDB指南---18、聚合命令

    摘要:上一篇文章指南下一篇文章為在集合上執(zhí)行基本的聚合任務(wù)提供了一些命令。也可以給傳遞一個查詢文檔,會計算查詢結(jié)果的數(shù)量對分頁顯示來說總數(shù)非常必要共個,目前顯示個。使用時必須指定集合和鍵。指定要進行分組的集合。 上一篇文章:MongoDB指南---17、MapReduce下一篇文章: MongoDB為在集合上執(zhí)行基本的聚合任務(wù)提供了一些命令。這些命令在聚合框架出現(xiàn)之前就已經(jīng)存在了,現(xiàn)在(大多...

    why_rookie 評論0 收藏0
  • MongoDB指南---18、聚合命令

    摘要:上一篇文章指南下一篇文章為在集合上執(zhí)行基本的聚合任務(wù)提供了一些命令。也可以給傳遞一個查詢文檔,會計算查詢結(jié)果的數(shù)量對分頁顯示來說總數(shù)非常必要共個,目前顯示個。使用時必須指定集合和鍵。指定要進行分組的集合。 上一篇文章:MongoDB指南---17、MapReduce下一篇文章: MongoDB為在集合上執(zhí)行基本的聚合任務(wù)提供了一些命令。這些命令在聚合框架出現(xiàn)之前就已經(jīng)存在了,現(xiàn)在(大多...

    raoyi 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<