mongodb文檔 aggregate章節閱讀的筆記

來源:互聯網
上載者:User

標籤:

aggregate 包含3中不同的類型:

1.管道

2.單一功能彙總   (count,group,distinct)

3.map-reduce


管道運算式


管道運算式僅能操作當前在管道中的文檔,不能代表其他的文檔.

通常,運算式是沒有狀態的,並且在彙總過程中被計算,但是有一個例外的:累加器運算式


累加器,只能用在group  管道操作器中,主要的狀態有:總共,最大,最小,和關聯資料.



最佳化的方式:

$match he $sort管道操作器可以利用索引,當他們出現在管道的第一個位置.避免掃描集合內所有

文檔.

從2.4開始引入的$geoNear管道操作器可以利用geospatial index.當使用,必須放在管道的開始位置.


儘管管道使用了索引.彙總仍然需要訪問實際的文檔.索引無法完全覆蓋彙總管道.


初期過濾(Early Filtering)

如果彙總管道操作僅僅需要整個集合的部分資料,那麼使用$match,$limit, 和 $skip 步驟來限制進入管道

的文檔數量.在管道的入口端,$match操作會使用合適的索引來掃描,僅僅使複合條件的文檔進入該管道.


在管道的開始處使用$match,緊接著使用$sort邏輯上等價於簡單的利用sort的查詢,使用索引.如果可能,

盡量將$match操作器放在管道的開始端.


額外的功能:

彙總索引有一個內部的最佳化階段以提高彙總效能.

彙總管道支援在分區的集合上進行.



mongodb 的mapreduce操作

map方法處理每一個輸入文檔,map方法最後產生key-value 對.



輸出的限制:必須在 bson document 的尺寸範圍內,當前為16M.


mapreduce  輸入輸出的集合均支援在分區中的集合.




內建的最佳化機制:

1.project最佳化:彙總管道可以確定管道中需要多少個欄位,因此,

管道只使用需要用到的欄位


管道順序最佳化:

 如果寫成了:

$sort=>$match   會最佳化成:

$match=>$sort



{ $sort: { age : -1 } },

{ $match: { status: ‘A‘ } }


{ $match: { status: ‘A‘ } },

{ $sort: { age : -1 } }



{ $skip: 10 },

{ $limit: 5 }


{ $limit: 15 },

{ $skip: 10 }

 減少$skip的數量



{ $redact: { $cond: { if: { $eq: [ "$level", 5 ] }, then: "$$PRUNE", else: "$$DESCEND" } } },

{ $match: { year: 2014, category: { $ne: "Z" } } }


{ $match: { year: 2014 } },

{ $redact: { $cond: { if: { $eq: [ "$level", 5 ] }, then: "$$PRUNE", else: "$$DESCEND" } } },

{ $match: { year: 2014, category: { $ne: "Z" } } }


合并最佳化

$sort + $limit 合并最佳化

當sort  後面緊接著 是limit.最佳化器會將 limit合并到 sort中,這樣   就只需要存取前 n個值.

節省了記憶體.

The optimization will still apply when allowDiskUse is true and the n items exceed the aggregation memory limit (page 403).



$limit + $limit合并最佳化

當連續2個$limit在一起時,會合并成1個,

並且選用  $limit較小的那個數字


連續兩個 $skip

連續兩個的$skip會合并成一個, 後面的數字為兩個$skip的和.


連續兩個的$match. 會合并成1個,條件會合并在一起.



{ $sort: { age : -1 } },

{ $skip: 10 },

{ $limit: 5 }



{ $sort: { age : -1 } },

{ $limit: 15 }

{ $skip: 10 }



example:

{ $sort: { age : -1 } },

{ $skip: 10 },

{ $limit: 5 }  

====>>>>

{ $sort: { age : -1 } },

{ $limit: 15 }

{ $skip: 10 }

====>>>>

$sort+$limit合并




{$limit: 100 },

{$skip: 5 },

{$limit: 10 },

{$skip: 2 }


==========>>>>>>>

{$limit: 100 },

{$limit: 15},

{$skip: 5 },

{$skip: 2 }

=========>>>>>>>>>

{ $limit: 15 },

{ $skip: 7 }



Result Size Restrictions

manage result sets that exceed this limit, the aggregate command can return result sets of any size if the command

return a cursor or store the results to a collection.

Changed in version 2.6: The aggregate command can return results as a cursor or store the results in a collection,

which are not subject to the size limit. The db.collection.aggregate() returns a cursor and can return result

sets of any size.



Memory Restrictions

Changed in version 2.6.

Pipeline stages have a limit of 100 megabytes of RAM. If a stage exceeds this limit, MongoDB will produce an error.

To allow for the handling of large datasets, use the allowDiskUse option to enable aggregation pipeline stages to

write data to temporary files.



 當彙總操作執行在分區的集合中時,彙總管道被拆分成兩部分.第一個管道執行在每個分區.或者當初期$match可以

通過分區key的斷言排除一些分區集.管道只運行在相關聯的分區上.

第二個管道運行在主分區上.合并第一個階段執行的結果.並且在合并的結果的基礎上在執行.主分區將最後的結果轉寄到

mongos.在2.6 以前.第二個管道運行在mongos上.]



map reduce  執行輸入/輸出在分區的collection.

如果是輸入的集合為分區的集合,mongos 會自動平行地調度 map-reduce到每個分區中.無需額外處理.

如果輸出的集合為分區的集合,

If the out field for mapReduce has the sharded value, MongoDB shards the output collection using the _id field

as the shard key.

? If the output collection does not exist, MongoDB creates and shards the collection on the _id field.

? For a new or an empty sharded collection, MongoDB uses the results of the first stage of the map-reduce

operation to create the initial chunks distributed among the shards.

? mongos dispatches, in parallel, a map-reduce post-processing job to every shard that owns a chunk. During

the post-processing, each shard will pull the results for its own chunks from the other shards, run the final

reduce/finalize, and write locally to the output collection.



Map Reduce Concurrency





Return States with Populations above 10 Million

SELECT state, SUM(pop) AS totalPop

FROM zipcodes

GROUP BY state

HAVING totalPop >= (10*1000*1000)



db.zipcodes.aggregate( { $group :

{ _id : "$state",

totalPop : { $sum : "$pop" } } },

{ $match : {totalPop : { $gte : 10*1000*1000 } } } )



Return Average City Population by State

根據stat和city 取平均值.

db.zipcodes.aggregate( [

{ $group : { _id : { state : "$state", city : "$city" }, pop : { $sum : "$pop" } } },

{ $group : { _id : "$_id.state", avgCityPop : { $avg : "$pop" } } }

] )


// 對應的sql語句

select state, avg(sum_pop) from (select state, city, sum(pop) as sum_pop from zipcodes group by city, state) as temp 

group by temp.state


Return Largest and Smallest Cities by State


 返回最大.最小值


db.zipcodes.aggregate( { $group:

{ _id: { state: "$state", city: "$city" },

pop: { $sum: "$pop" } } },

{ $sort: { pop: 1 } },

{ $group:

{ _id : "$_id.state",

biggestCity: { $last: "$_id.city" },

biggestPop:

{ $last: "$pop" },

smallestCity: { $first: "$_id.city" },

smallestPop: { $first: "$pop" } } },

// the following $project is optional, and

// modifies the output format.

{ $project:

{ _id: 0,

state: "$_id",

biggestCity: { name: "$biggestCity", pop: "$biggestPop" },

smallestCity: { name: "$smallestCity", pop: "$smallestPop" } } } )




Return the Five Most Common “Likes”



db.users.aggregate(

[

{ $unwind : "$likes" },   //   這裡得注釋一下:? The $unwind operator separates each value in the likes array, and creates a new version of the source document for every element in the array.   拆分數組用的...

{ $group : { _id : "$likes" , number : { $sum : 1 } } },

{ $sort : { number : -1 } },

{ $limit : 5 }

]

)





map-reduce   的例子:


資料結構:


{

_id: ObjectId("50a8240b927d5d8b5891743c"),

cust_id: "abc123",

ord_date: new Date("Oct 04, 2012"),

status: ‘A‘,

price: 25,

items: [ { sku: "mmm", qty: 5, price: 2.5 },

{ sku: "nnn", qty: 5, price: 2.5 } ]

}



Return the Total Price Per Customer


map   方法:

var mapFunction1 = function() {

emit(this.cust_id, this.price);

};


reduce 方法:

var reduceFunction1 = function(keyCustId, valuesPrices) {

return Array.sum(valuesPrices);

};


結合使用:

db.orders.mapReduce(

mapFunction1,

reduceFunction1,

{ out: "map_reduce_example" }     //指定輸出到   "map_reduce_example"  這個集合中

)


========

待續...

文檔:

http://pan.baidu.com/s/1jiFOM



mongodb文檔 aggregate章節閱讀的筆記

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.