在 MongoDB 文檔中,Map-Reduce(映射歸約)是一種將大量數(shù)據(jù)壓縮成有用的聚合結(jié)果的數(shù)據(jù)處理范式。MongoDB 使用 mapReduce 命令來實(shí)現(xiàn)映射歸約操作。映射歸約通常用來處理大型數(shù)據(jù)。
mapReduce 命令的基本格式為:
>db.collection.mapReduce(
function() {emit(key,value);}, //map function
function(key,values) {return reduceFunction}, //reduce function
{
out: collection,
query: document,
sort: document,
limit: number
}
)
mapReduce 函數(shù)首先查詢集合,然后將結(jié)果文檔利用 emit 函數(shù)映射為鍵值對(duì),然后再根據(jù)有多個(gè)值的鍵來簡化。
上述語法格式中:
以下面這個(gè)存儲(chǔ)用戶發(fā)帖的文檔結(jié)構(gòu)。該文檔存儲(chǔ)用戶的用戶名(user_name)和發(fā)帖狀態(tài)(status)。
{
"post_text": "tutorialspoint is an awesome website for tutorials",
"user_name": "mark",
"status":"active"
}
在 posts 集合上使用 mapReduce 函數(shù)選擇所有的活躍帖子,將它們基于用戶名組合起來,然后計(jì)算每個(gè)用戶的發(fā)帖量。代碼如下:
>db.posts.mapReduce(
function() { emit(this.user_id,1); },
function(key, values) {return Array.sum(values)},
{
query:{status:"active"},
out:"post_total"
}
)
上面的 mapReduce 查詢輸出結(jié)果如下:
{
"result" : "post_total",
"timeMillis" : 9,
"counts" : {
"input" : 4,
"emit" : 4,
"reduce" : 2,
"output" : 2
},
"ok" : 1,
}
結(jié)果顯示,只有 4 個(gè)文檔符合查詢條件(status:"active"
),于是 map
函數(shù)就生成了 4 個(gè)帶有鍵值對(duì)的文檔,而最終 reduce
函數(shù)將具有相同鍵值的映射文檔變?yōu)榱?2 個(gè)。
要想查看 mapReduce
查詢的結(jié)果,使用 find
操作符。
>db.posts.mapReduce(
function() { emit(this.user_id,1); },
function(key, values) {return Array.sum(values)},
{
query:{status:"active"},
out:"post_total"
}
).find()
上述查詢的結(jié)果如下,顯示出用戶 tom 和 mark 都發(fā)了 2 個(gè)活躍的帖子。
{ "_id" : "tom", "value" : 2 }
{ "_id" : "mark", "value" : 2 }
MapReduce 查詢同樣也可以用來構(gòu)建大型復(fù)雜的聚合查詢,自定義 JavaScript 函數(shù)使得 MapReduce 更為靈活與強(qiáng)大。