欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Mongodb?多文檔聚合操作處理方法(Map-reduce?函數(shù))

 更新時間:2023年07月25日 14:42:57   作者:Ethanchen's?notes  
這篇文章主要介紹了Mongodb多文檔聚合操作處理方法(Map-reduce函數(shù)),本文通過示例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

聚合

聚合操作處理多個文檔并返回計算結果。您可以使用聚合操作來:

  • 將多個文檔中的值分組在一起。
  • 對分組數(shù)據(jù)執(zhí)行操作以返回單個結果。
  • 分析數(shù)據(jù)隨時間的變化。

要執(zhí)行聚合操作,您可以使用:

  • 聚合管道
  • 單一目的聚合方法
  • Map-reduce 函數(shù)

Map-reduce 函數(shù)

在mongoshell 中,該db.collection.mapReduce() 方法是命令的包裝器mapReduce。下面的例子使用該db.collection.mapReduce()方法。

定義: db.collection.mapReduce(map,reduce, { <options> })

該map功能有以下要求:

  • 在map函數(shù)中,將當前文檔引用為函數(shù)中的this。
  • 該map函數(shù)不應出于任何原因訪問數(shù)據(jù)庫。
  • 該map函數(shù)應該是純粹的,或者對函數(shù)之外沒有影響(即副作用)。
  • 該map函數(shù)可以選擇調(diào)用emit(key,value)任意次數(shù)來創(chuàng)建key與關聯(lián)的輸出文檔value。
# 原型如下:
function() {
   ...
   emit(key, value);
}

該reduce函數(shù)表現(xiàn)出以下行為:

  • 該reduce函數(shù)不應訪問數(shù)據(jù)庫,即使是執(zhí)行讀取操作。
  • 該reduce功能不應影響外部系統(tǒng)。
  • reduceMongoDB 可以針對同一個鍵多次調(diào)用該函數(shù)。在這種情況下,該鍵的函數(shù)的先前輸出將成為該鍵的reduce 下一個函數(shù)調(diào)用的輸入值之一 。
  • 該reduce函數(shù)可以訪問參數(shù)中定義的變量scope。
# 該reduce函數(shù)具有以下原型:
function(key, values) {
   ...
   return result;
}

插入測試數(shù)據(jù)。如下:

sit_rs1:PRIMARY> db.orders.insertMany([
...    { _id: 1, cust_id: "A", ord_date: new Date("2023-06-01"), price: 15, items: [ { sku: "apple", qty: 5, price: 2.5 }, { sku: "apples", qty: 5, price: 2.5 } ], status: "1" },
...    { _id: 2, cust_id: "A", ord_date: new Date("2023-06-08"), price: 60, items: [ { sku: "apple", qty: 8, price: 2.5 }, { sku: "banana", qty: 5, price: 10 } ], status: "1" },
...    { _id: 3, cust_id: "B", ord_date: new Date("2023-06-08"), price: 55, items: [ { sku: "apple", qty: 10, price: 2.5 }, { sku: "pears", qty: 10, price: 2.5 } ], status: "1" },
...    { _id: 4, cust_id: "B", ord_date: new Date("2023-06-18"), price: 26, items: [ { sku: "apple", qty: 10, price: 2.5 } ], status: "1" },
...    { _id: 5, cust_id: "B", ord_date: new Date("2023-06-19"), price: 40, items: [ { sku: "banana", qty: 5, price: 10 } ], status: "1"},
...    { _id: 6, cust_id: "C", ord_date: new Date("2023-06-19"), price: 38, items: [ { sku: "carrots", qty: 10, price: 1.0 }, { sku: "apples", qty: 10, price: 2.5 } ], status: "1" },
...    { _id: 7, cust_id: "C", ord_date: new Date("2023-06-20"), price: 21, items: [ { sku: "apple", qty: 10, price: 2.5 } ], status: "1" },
...    { _id: 8, cust_id: "D", ord_date: new Date("2023-06-20"), price: 76, items: [ { sku: "banana", qty: 5, price: 10 }, { sku: "apples", qty: 10, price: 2.5 } ], status: "1" },
...    { _id: 9, cust_id: "D", ord_date: new Date("2023-06-20"), price: 51, items: [ { sku: "carrots", qty: 5, price: 1.0 }, { sku: "apples", qty: 10, price: 2.5 }, { sku: "apple", qty: 10, price: 2.5 } ], status: "1" },
...    { _id: 10, cust_id: "D", ord_date: new Date("2023-06-23"), price: 23, items: [ { sku: "apple", qty: 10, price: 2.5 } ], status: "1" }
... ])
{
        "acknowledged" : true,
        "insertedIds" : [
                1,
                2,
                3,
                4,
                5,
                6,
                7,
                8,
                9,
                10
        ]
}
sit_rs1:PRIMARY> db.orders.find()
{ "_id" : 4, "cust_id" : "B", "ord_date" : ISODate("2023-06-18T00:00:00Z"), "price" : 26, "items" : [ { "sku" : "apple", "qty" : 10, "price" : 2.5 } ], "status" : "1" }
{ "_id" : 6, "cust_id" : "C", "ord_date" : ISODate("2023-06-19T00:00:00Z"), "price" : 38, "items" : [ { "sku" : "carrots", "qty" : 10, "price" : 1 }, { "sku" : "apples", "qty" : 10, "price" : 2.5 } ], "status" : "1" }
{ "_id" : 1, "cust_id" : "A", "ord_date" : ISODate("2023-06-01T00:00:00Z"), "price" : 15, "items" : [ { "sku" : "apple", "qty" : 5, "price" : 2.5 }, { "sku" : "apples", "qty" : 5, "price" : 2.5 } ], "status" : "1" }
{ "_id" : 2, "cust_id" : "A", "ord_date" : ISODate("2023-06-08T00:00:00Z"), "price" : 60, "items" : [ { "sku" : "apple", "qty" : 8, "price" : 2.5 }, { "sku" : "banana", "qty" : 5, "price" : 10 } ], "status" : "1" }
{ "_id" : 9, "cust_id" : "D", "ord_date" : ISODate("2023-06-20T00:00:00Z"), "price" : 51, "items" : [ { "sku" : "carrots", "qty" : 5, "price" : 1 }, { "sku" : "apples", "qty" : 10, "price" : 2.5 }, { "sku" : "apple", "qty" : 10, "price" : 2.5 } ], "status" : "1" }
{ "_id" : 3, "cust_id" : "B", "ord_date" : ISODate("2023-06-08T00:00:00Z"), "price" : 55, "items" : [ { "sku" : "apple", "qty" : 10, "price" : 2.5 }, { "sku" : "pears", "qty" : 10, "price" : 2.5 } ], "status" : "1" }
{ "_id" : 5, "cust_id" : "B", "ord_date" : ISODate("2023-06-19T00:00:00Z"), "price" : 40, "items" : [ { "sku" : "banana", "qty" : 5, "price" : 10 } ], "status" : "1" }
{ "_id" : 7, "cust_id" : "C", "ord_date" : ISODate("2023-06-20T00:00:00Z"), "price" : 21, "items" : [ { "sku" : "apple", "qty" : 10, "price" : 2.5 } ], "status" : "1" }
{ "_id" : 8, "cust_id" : "D", "ord_date" : ISODate("2023-06-20T00:00:00Z"), "price" : 76, "items" : [ { "sku" : "banana", "qty" : 5, "price" : 10 }, { "sku" : "apples", "qty" : 10, "price" : 2.5 } ], "status" : "1" }
{ "_id" : 10, "cust_id" : "D", "ord_date" : ISODate("2023-06-23T00:00:00Z"), "price" : 23, "items" : [ { "sku" : "apple", "qty" : 10, "price" : 2.5 } ], "status" : "1" }

示例:按客戶統(tǒng)計

對集合 orders 執(zhí)行map-reduce操作, 按 cust_id 進行分組, 然后統(tǒng)計每個客戶的 price 計算總和,如下:

首先, 我們需要 定義map函數(shù)來處理每個輸入文檔:

  • 在函數(shù)中,this指的是map-reduce操作正在處理的文檔。
  • 該函數(shù)將每個文檔的 price 映射為 cust_id,并發(fā)出 cust_id 和 price 。
sit_rs1:PRIMARY> var myMapFun = function() {
...    emit(this.cust_id, this.price);
... };
sit_rs1:PRIMARY> print(myMapFun)
function() {
   emit(this.cust_id, this.price);
}

然后,用兩個參數(shù) keyCustId 和 valuesPrices 定義相應的reduce函數(shù)。 這里需要調(diào)用數(shù)組的 sum 方法計算客戶訂單總價。

  • valuesPrices 是一個數(shù)組,其元素是map函數(shù)發(fā)出的price 字段的值,并按 keyCustId 分組。
  • 該函數(shù)將 valuesPrice 數(shù)組縮減為其元素的總和
# 計算數(shù)組元素總和
sit_rs1:PRIMARY> Array.sum([2,2,6,8])
18
# 計算數(shù)組平均值
sit_rs1:PRIMARY> Array.avg([1,2,3])
2
sit_rs1:PRIMARY> var myReduceFun = function(keyCustId, valuesPrices) {
...    return Array.sum(valuesPrices);
... };
sit_rs1:PRIMARY> print(myReduceFun)
function(keyCustId, valuesPrices) {
   return Array.sum(valuesPrices);
}

最后,使用 myMapFun 函數(shù)和 myReduceFun 函數(shù)對集合 orders 中的所有文檔執(zhí)行map-reduce統(tǒng)計:

  • out: 指定map-reduce操作結果的位置。您可以輸出到集合、通過操作輸出到集合或內(nèi)聯(lián)輸出。
  • 此操作將結果輸出到名為 的集合 map_reduce_out。如果該 map_reduce_out 集合已存在,則該操作將使用此 Map-Reduce 操作的結果替換內(nèi)容。
sit_rs1:PRIMARY> db.orders.mapReduce(
...    myMapFun,
...    myReduceFun,
...    { out: "map_reduce_out" }
... )
{
        "result" : "map_reduce_out",
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1690259241, 6),
                "signature" : {
                        "hash" : BinData(0,"Kur+ueslJYcT5oExd8ujPIC/J3Q="),
                        "keyId" : NumberLong("7205479298910650370")
                }
        },
        "operationTime" : Timestamp(1690259241, 6)
}

查詢 map_reduce_out 集合以驗證結果是否正確:

sit_rs1:PRIMARY> db.map_reduce_out.find().sort( { _id: 1 } )
{ "_id" : "A", "value" : 75 }
{ "_id" : "B", "value" : 121 }
{ "_id" : "C", "value" : 59 }
{ "_id" : "D", "value" : 150 }
# 檢查 cust_id 為 A 的客戶, 總和是 75 正確
sit_rs1:PRIMARY> db.orders.find({ "cust_id" : "A"}, {"price": 1})
{ "_id" : 1, "price" : 15 }
{ "_id" : 2, "price" : 60 }
# 檢查 cust_id 為 B 的客戶,總和是 121 正確
sit_rs1:PRIMARY> db.orders.find({ "cust_id" : "B"}, {"price": 1})
{ "_id" : 4, "price" : 26 }
{ "_id" : 3, "price" : 55 }
{ "_id" : 5, "price" : 40 }

示例:按日期統(tǒng)計

按日期統(tǒng)計,和上面示例一樣,只需要把 map 函數(shù)重新定義如下,將每個文檔的 price 映射為 ord_date,并發(fā)出 ord_date 和 price 。

sit_rs1:PRIMARY> var myMapFun2 = function() {
...     emit(this.ord_date, this.price);
... };
sit_rs1:PRIMARY> print(myMapFun2)
function() {
    emit(this.ord_date, this.price);
}

然后,用兩個參數(shù) keyOrdDate 和 valuesPrices 定義相應的reduce函數(shù)。 這里需要調(diào)用數(shù)組的 avg 方法計算平均客單價。

  • valuesPrices 是一個數(shù)組,其元素是map函數(shù)發(fā)出的 price 字段的值,并按 keyOrdDate 分組。
  • 該函數(shù)將 valuesPrice 數(shù)組縮減為其元素的總和的平均值
sit_rs1:PRIMARY> var myReduceFun2 = function(keyOrdDate, valuesPrices) {
...    return Array.avg(valuesPrices);
... };
sit_rs1:PRIMARY> print(myReduceFun2)
function(keyOrdDate, valuesPrices) {
   return Array.avg(valuesPrices);
}

最后,使用 myMapFun2 函數(shù)和 myReduceFun2 函數(shù)對集合 orders 中的所有文檔執(zhí)行map-reduce統(tǒng)計:

sit_rs1:PRIMARY> db.orders.mapReduce(
...    myMapFun2,
...    myReduceFun2,
...    { out: "map_reduce_out2" }
... )
{
        "result" : "map_reduce_out2",
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1690265083, 8),
                "signature" : {
                        "hash" : BinData(0,"pCWskY3HjLGEjSk00ARYdZKECDE="),
                        "keyId" : NumberLong("7205479298910650370")
                }
        },
        "operationTime" : Timestamp(1690265083, 8)
}

查詢 map_reduce_out2 集合以驗證結果是否正確:

sit_rs1:PRIMARY> db.map_reduce_out2.find()
{ "_id" : ISODate("2023-06-08T00:00:00Z"), "value" : 57.5 }
{ "_id" : ISODate("2023-06-01T00:00:00Z"), "value" : 15 }
{ "_id" : ISODate("2023-06-18T00:00:00Z"), "value" : 26 }
{ "_id" : ISODate("2023-06-20T00:00:00Z"), "value" : 49.333333333333336 }
{ "_id" : ISODate("2023-06-23T00:00:00Z"), "value" : 23 }
{ "_id" : ISODate("2023-06-19T00:00:00Z"), "value" : 39 }
# 檢查日期2023-06-08的訂單平均值
sit_rs1:PRIMARY> db.orders.find({ "ord_date" : ISODate("2023-06-08T00:00:00Z")}, {"price": 1})
{ "_id" : 2, "price" : 60 }
{ "_id" : 3, "price" : 55 }
sit_rs1:PRIMARY> print((60+55)/2)
57.5
# 檢查日期2023-06-20的訂單平均值
sit_rs1:PRIMARY> db.orders.find({ "ord_date" : ISODate("2023-06-20T00:00:00Z")}, {"price": 1})
{ "_id" : 9, "price" : 51 }
{ "_id" : 7, "price" : 21 }
{ "_id" : 8, "price" : 76 }
sit_rs1:PRIMARY> print((51+21+76)/3)
49.333333333333336

對于需要自定義功能的 Map-Reduce 操作,MongoDB 從 4.4 版本開始提供 $accumulator 和 $function 聚合運算符。使用這些運算符在 JavaScript 中自定義聚合表達式。

  • 聚合管道作為 Map-Reduce 的替代方案, 聚合管道提供比 Map-Reduce 操作更好的性能和可用性。
  • 可以使用聚合管道運算符(例如 $group、$merge等)重寫 Map-reduce 操作。

到此這篇關于Mongodb 多文檔聚合操作處理方法(Map-reduce 函數(shù))的文章就介紹到這了,更多相關Mongodb 聚合操作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • mongodb3.4集群搭建實戰(zhàn)之高可用的分片+副本集

    mongodb3.4集群搭建實戰(zhàn)之高可用的分片+副本集

    這篇文章主要給大家介紹了關于mongodb3.4集群搭建實戰(zhàn)之高可用的分片+副本集的相關資料,文中通過示例代碼將實現(xiàn)的步驟一步步的介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面跟著小編來一起學習學習吧。
    2017-08-08
  • mongodb與mysql命令詳細對比

    mongodb與mysql命令詳細對比

    MongoDB的好處挺多的,比如多列索引,查詢時可以用一些統(tǒng)計函數(shù),支持多條件查詢,但是目前多表查詢是不支持的,可以想辦法通過數(shù)據(jù)冗余來解決多表查詢的問題
    2013-08-08
  • Spring Boot中使用MongoDB數(shù)據(jù)庫的方法

    Spring Boot中使用MongoDB數(shù)據(jù)庫的方法

    MongoDB是一個介于關系數(shù)據(jù)庫和非關系數(shù)據(jù)庫之間的產(chǎn)品,是非關系數(shù)據(jù)庫當中功能最豐富,最像關系數(shù)據(jù)庫的。他支持的數(shù)據(jù)結構非常松散,是類似json的bjson格式,因此可以存儲比較復雜的數(shù)據(jù)類型。Mongo最大的特點是他支持的查詢語言非常強大
    2018-02-02
  • window下mongodb在dos下服務器啟動及連接

    window下mongodb在dos下服務器啟動及連接

    這篇文章主要介紹了window下mongodb在dos下服務器啟動及連接的相關資料,需要的朋友可以參考下
    2017-06-06
  • mongodb中非常好用的Aggregate入門教程

    mongodb中非常好用的Aggregate入門教程

    這篇文章主要給大家介紹了關于mongodb中非常好用的Aggregate的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用mongodb具有一定的參考學習價值,需要的朋友們下面來一起看看吧
    2018-12-12
  • Win10 安裝 MongoDB 3.6.5 失敗的問題及解決方法

    Win10 安裝 MongoDB 3.6.5 失敗的問題及解決方法

    這篇文章主要介紹了Win10 安裝 MongoDB 3.6.5 失敗的問題及解決方法,需要的朋友可以參考下
    2018-05-05
  • MongoDB4.28開啟權限認證配置用戶密碼登錄功能

    MongoDB4.28開啟權限認證配置用戶密碼登錄功能

    這篇文章主要介紹了MongoDB4.28開啟權限認證配置用戶名和密碼認證登錄,本文分步驟給大家介紹開啟認證登錄的方法,需要的朋友可以參考下
    2022-01-01
  • Mongodb實現(xiàn)定時備份與恢復的方法教程

    Mongodb實現(xiàn)定時備份與恢復的方法教程

    這篇文章主要給大家介紹了Mongodb實現(xiàn)定時備份與恢復的方法教程,文中通過示例代碼介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面跟著小編一起來學習學習吧。
    2017-06-06
  • 基于MongoDB數(shù)據(jù)庫的數(shù)據(jù)類型和$type操作符詳解

    基于MongoDB數(shù)據(jù)庫的數(shù)據(jù)類型和$type操作符詳解

    下面小編就為大家?guī)硪黄贛ongoDB數(shù)據(jù)庫的數(shù)據(jù)類型和$type操作符詳解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • MongoDB插入、更新、刪除文檔實現(xiàn)代碼

    MongoDB插入、更新、刪除文檔實現(xiàn)代碼

    本文通過實例代碼給大家簡單介紹了mongodb插入、更新、刪除文檔的方法,需要的的朋友參考下吧
    2017-04-04

最新評論