256_Mongodb_聚合操作

      網(wǎng)友投稿 785 2025-04-01

      聚合操作

      MongoDB的聚合操作是通過數(shù)據(jù)處理管道(pipeline)來實現(xiàn)的,一次操作可以通過多個管道來處理,且管道是有順序的

      聚合操作可用于實現(xiàn)分組, 排序, 數(shù)值運算, 條件篩選,多表關(guān)聯(lián)查詢等

      聚合管道包含非常豐富的聚合階段,下面是最常用的聚合階段

      階段

      描述

      $group

      分組

      $project

      顯示字段

      $match

      篩選條件

      $sort/$skip/$limit

      排序分頁

      $lookup

      多表關(guān)聯(lián)

      $unwind

      展開數(shù)組

      $out

      結(jié)果匯入新表

      $count

      文檔計數(shù)

      256_Mongodb_聚合操作

      $project:修改輸入文檔的結(jié)構(gòu)。可以用來重命名、增加或刪除域,也可以用于創(chuàng)建計算結(jié)果以及嵌套文檔。 $match:用于過濾數(shù)據(jù),只輸出符合條件的文檔。$match使用MongoDB的標(biāo)準(zhǔn)查詢操作。 $limit:用來限制MongoDB聚合管道返回的文檔數(shù)。 $skip:在聚合管道中跳過指定數(shù)量的文檔,并返回余下的文檔。 $unwind:將文檔中的某一個數(shù)組類型字段拆分成多條,每條包含數(shù)組中的一個值。 $group:將集合中的文檔分組,可用于統(tǒng)計結(jié)果。 $sort:將輸入文檔排序后輸出。 $geoNear:輸出接近某一地理位置的有序文檔

      語法格式

      db.collection.aggregate([ {pipeline_1}, {pipeline_2} …. ])

      1 聚合-$group

      $group 聚合操作符主要作用是對文檔中特定字段進行分組,搭配下面的操作符對結(jié)果進行計算

      操作符

      說明

      $sum

      利用$group分組后,對同組的文檔進行 計算總和

      $avg

      利用$group分組后,對同組的文檔進行 計算平均值

      $min

      利用$group分組后,對同組的文檔進行 獲取集合中所有文檔對應(yīng)值得最小值。

      $max

      利用$group分組后,對同組的文檔進行 獲取集合中所有文檔對應(yīng)值得最大值。

      $push

      利用$group分組后,對同組的文檔進行 以數(shù)組的方式顯示指定的字段

      $addToSet

      將值加入一個數(shù)組中,會判斷是否有重復(fù)的值,以數(shù)組的方式顯示字段不重復(fù)的值

      $first

      根據(jù)資源文檔的排序獲取第一個文檔數(shù)據(jù)。

      $last

      根據(jù)資源文檔的排序獲取最后一個文檔數(shù)據(jù)

      db.sales.drop() db.sales.insertMany([ { "_id" : 1, "item" : "abc", "price" : NumberDecimal("10"), "quantity" : NumberInt("2"), "date" : ISODate("2014-03-01T08:00:00Z") }, { "_id" : 2, "item" : "jkl", "price" : NumberDecimal("20"), "quantity" : NumberInt("1"), "date" : ISODate("2014-03-01T09:00:00Z") }, { "_id" : 3, "item" : "xyz", "price" : NumberDecimal("5"), "quantity" : NumberInt( "10"), "date" : ISODate("2014-03-15T09:00:00Z") }, { "_id" : 4, "item" : "xyz", "price" : NumberDecimal("5"), "quantity" : NumberInt("20") , "date" : ISODate("2014-04-04T11:21:39.736Z") }, { "_id" : 5, "item" : "abc", "price" : NumberDecimal("10"), "quantity" : NumberInt("10") , "date" : ISODate("2014-04-04T21:23:13.331Z") }, { "_id" : 6, "item" : "def", "price" : NumberDecimal("7.5"), "quantity": NumberInt("5" ) , "date" : ISODate("2015-06-04T05:08:13Z") }, { "_id" : 7, "item" : "def", "price" : NumberDecimal("7.5"), "quantity": NumberInt("10") , "date" : ISODate("2015-09-10T08:43:00Z") }, { "_id" : 8, "item" : "abc", "price" : NumberDecimal("10"), "quantity" : NumberInt("5" ) , "date" : ISODate("2016-02-06T20:20:13Z") }, ]) db.sales.find()

      語法格式

      >db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION) db.collection.aggregate( [{ $group: {"_id": "$<分組字段名稱>",<顯示結(jié)果的名稱>:{<操作符>: "$<計算的字段>"}} } ]) # select item, count( quantity ) from sales group by item db.sales.aggregate( [{$group:{"_id" : "$item", "sum":{$sum :"$quantity"} } } ]) db.sales.aggregate([{$group: {"_id": null, "count":{$sum: 1}}}]) //8 db.sales.find().size()

      2 顯示字段 $project

      文檔字段較多, 只想查詢幾個字段, 將預(yù)顯示的字段設(shè)定為 “1”;? 其余字段默認(rèn)不顯示(也可以設(shè)置為”0”), “_id” 較為特別, 默認(rèn)顯示

      # 常規(guī)顯示操作 db.sales.aggregate({"$project": {"_id":0, "item":1}}) # 搭配其他操作符 語法 db.collection.aggrate([ { $project: { <顯示結(jié)果的名稱1>:{<操作符1> : <操作符條件2>}。 <顯示結(jié)果的名稱2>:{<操作符2>:<操作符條件2>} } } ]) # $substr 需要三個參數(shù):字符串, 起始參數(shù)(0 代表第一個字符), 長度參數(shù)(如為負表示截取到結(jié)尾) db.sales.aggregate({"$project": {"_id":0, "item_xxxx": {$substr: ["$item", 0,1]}}}) # $switch 對指定字段進行一系列條件判斷,符合則返回 db.sales.aggregate({[{"$project": {"priceSwitch": {$switch: {branches: [ {case: {$gt: ["$price", 5], then: "price>5"}}, {case: {$lt: ["$price", 10], then: "price<10"}}], default:"price <=5 & price >=10"}} } }])

      3 數(shù)據(jù)排序/跳過限制文檔數(shù)量 $sort $skip $limit

      需要對報表進行分頁, 將”$sort” “skip” “$limit” 一起使用

      操作符

      說明

      $sort

      升序 1 降序 -1

      $skip

      顯示文檔時 跳過只讀數(shù)量的文檔

      $limit

      限制顯示的文檔數(shù)量

      /* SELECT date, Sum(( price * quantity )) AS totalSaleAmount, Avg(quantity) AS averageQuantity, Count(*) AS Count FROM sales GROUP BY Date(date) ORDER BY totalSaleAmount DESC */ db.sales.aggregate([ // First Stage { $match : { "date": { $gte: new ISODate("2014-01-01"), $lt: new ISODate("2015-01-01") } } }, // Second Stage { $group : { _id : { $dateToString: { format: "%Y-%m-%d", date: "$date" } }, totalSaleAmount: { $sum: { $multiply: [ "$price", "$quantity" ] } }, averageQuantity: { $avg: "$quantity" }, count: { $sum: 1 } } }, // Third Stage { $sort : { totalSaleAmount: -1 } } ])

      5 多表關(guān)聯(lián)查詢 $lookup

      找出集合中與另一個集合條件匹配的文檔, 類似關(guān)系型數(shù)據(jù)庫的join

      From 需要關(guān)聯(lián)另一個集合, localField: 集合中需關(guān)聯(lián)的鍵, foreignField 與另一個集合關(guān)聯(lián)的鍵 As 關(guān)聯(lián)后另外一個集合的數(shù)據(jù)嵌入至此字段下 db.orders.drop() db.orders.insert([ { "_id" : 1, "item" : "almonds", "price" : 12, "quantity" : 2 }, { "_id" : 2, "item" : "pecans", "price" : 20, "quantity" : 1 }, { "_id" : 3 } ]) // $lookup,多表關(guān)聯(lián) /* SELECT *, inventory_docs FROM orders WHERE inventory_docs IN ( SELECT * FROM inventory WHERE sku= orders.item ); */ db.orders.aggregate([ { $lookup: { from: "inventory", localField: "item", foreignField: "sku", as: "inventory_docs" } } ])

      6? 計算文檔數(shù)量 $count

      db.inventory.aggregate([{$match:{"qty":{$gte:50}}},{$count: "qty_count"}])

      7? 展開數(shù)組 $unwind

      將文檔中數(shù)組形式的數(shù)據(jù)拆分成數(shù)個文檔,如指定字段不存在,則不會進行拆分

      語法 db.collecton.aggregate([ {$unwind: {path: , includeArrayInde:, preserveNullAndEmptyArrays:}} ]) Path: 指定要拆分的數(shù)組,需要用”$”開頭 includeArrayInde: 每個數(shù)組在原數(shù)組中的位置 preserveNullAndEmptyArrays: 選擇是否輸出未拆分的文檔(如空) 默認(rèn)為false 例 db.inventory.aggregate( [ { $unwind: { path: "$tags", preserveNullAndEmptyArrays: true } }, { $group: { _id: "$tags", averageQty: { $avg: "$qty" } } }, { $sort: { "averageQty": -1 } } ] )

      db.inventory.aggregate( [ { $unwind: { path: "$tags", preserveNullAndEmptyArrays: true } }, { $group: { _id: "$tags", averageQty: { $avg: "$qty" } } }, { $sort: { "averageQty": -1 } }, { $skip: 2}, { $limit: 2} ] )

      8 $out

      將聚合出來的結(jié)果寫入一個指定的集合中,如果原集合中有索引,寫入的文檔違反索引,則寫入失敗

      // $out,將聚合結(jié)果匯入新表 db.inventory.aggregate( [ // First Stage { $unwind: { path: "$tags", preserveNullAndEmptyArrays: true } }, // Second Stage { $group: { _id: "$tags", averageQty: { $avg: "$qty" } } }, // Third Stage { $sort: { "averageQty": -1 } }, { $out : "tagsAvgQty" } ] ) db.tagsAvgQty.find();

      MapReduce

      MapReduce操作具有兩個階段:處理每個文檔并向每個輸入文檔發(fā)射一個或多個對象的map階 段,以及reduce組合map操作的輸出的階段。

      Map 通過鍵值對形式 將相同 key 的文檔 保存到 value 數(shù)組中,把結(jié)果集key value輸出給 reduce階段

      Reduce 根據(jù) key 對value 進行計算,然后再輸出

      語法 db.collection.mapreduce( , # javascript函數(shù),文檔拆分成key value , # key value進行計算 { Out: , Query: , #查詢/篩選條件 Limit: , #限制數(shù)量 Finalize: , # 修改reduce結(jié)果然后輸出 Scope: , # 指定map,reduce,finalize函數(shù)使用全局變量 jsMode: , #是否在mapreduce過程中將數(shù)據(jù)轉(zhuǎn)成bson格式 verbose: , #是否在結(jié)果中顯示時間 bypassDocumentValidation: #選擇是否略過數(shù)據(jù)校驗 } )

      db.inventory.find().size() db.inventory.find() // 示例 var mapFun = function() { // 類似hashmap的put方法,不一樣的地方在于同一個Key不是替換,而是追加 emit(this.status, this.qty); }; var reduceFun = function(keyCustId, valuesQty) { return Array.sum(valuesQty); }; db.inventory.mapReduce( mapFun, reduceFun, { out: "map_reduce_inventory" } ) db.map_reduce_inventory.find()

      MongoDB 數(shù)據(jù)結(jié)構(gòu)

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:wps表格邊框粗細怎么設(shè)置(wps表格怎么調(diào)整邊框線粗細)
      下一篇:excel2003外部引用數(shù)據(jù)的教程
      相關(guān)文章
      亚洲福利视频一区二区| 亚洲精品无AMM毛片| 亚洲日本中文字幕天堂网| 亚洲av成人中文无码专区| 中文字幕乱码亚洲无线三区| 国产亚洲sss在线播放| 亚洲国产精品一区二区三区在线观看| 亚洲精品美女视频| 亚洲第一页中文字幕| 亚洲精品国产第1页| 亚洲无砖砖区免费| 亚洲的天堂av无码| 亚洲一区二区三区91| 亚洲av乱码一区二区三区| 亚洲人精品亚洲人成在线| 亚洲一区二区三区乱码在线欧洲| 国产成人精品亚洲2020| 亚洲中文无码mv| 18禁亚洲深夜福利人口| 亚洲av无码专区在线观看素人| 亚洲精品无码久久久| 亚洲人成亚洲人成在线观看| 亚洲va中文字幕无码久久| 亚洲v高清理论电影| 少妇中文字幕乱码亚洲影视| 亚洲成a人片7777| 亚洲第一男人天堂| 亚洲av日韩av永久无码电影| 亚洲成a人片在线观看老师| 亚洲自偷自偷偷色无码中文| 亚洲AV无码乱码在线观看富二代| 亚洲天天做日日做天天看| 亚洲无圣光一区二区| 亚洲精品无码中文久久字幕| 亚洲AV无码一区二区三区鸳鸯影院 | 亚洲熟妇AV日韩熟妇在线| 亚洲AV日韩综合一区| 亚洲综合色成在线播放| 国产亚洲精品国产| 亚洲精品国产成人| 亚洲精品无码日韩国产不卡av|